0
votes

I'm creating a kernel module that intercept the unlink command and make a copy of the file that want to be unlinked. For now, I intercept the unlink command and im trying to print the path of the file but it doesn't work right.

I have a method that receive a char *path parameter and I use printk to show the path, but this print some rare strings like "\xe07l\xd3\xf"

asmlinkage int hacked_sys_unlink(const char *pathname)
{
    printk("RM_CATCHED: unlink( \"%s\" )\n", pathname);
    return original_sys_unlink(pathname);
}

When I unlink some file and use dmesg command i get this:

[ 1531.847856] RM_CATCHED: unlink( "`g\xcfYMV" )
[ 1531.848071] RM_CATCHED: unlink( "\xe07l\xd3\xf" )
[ 1534.851623] RM_CATCHED: unlink( "\xe07l\xd3\xf" )
[ 1534.852091] RM_CATCHED: unlink( "" )
[ 1541.861962] RM_CATCHED: unlink( "" )

How can I get the real path of the file like /path/to/file.txt?

2
I guess you need to fetch the filename in the same manner as the original unlink system call - Antti Haapala

2 Answers

1
votes

The core reason of getting rubbish printed instead of a nice real file name is that first you need to copy the string from user space into kernel space. Usually copy_from_user() function is used for that. In this case you have a NULL-terminated string, and there's a variation of that function called strncpy_from_user() which can be used instead.

To make things easier, it's best to follow what the original function does. It calls getname() function which eventually calls strncpy_from_user among lots of other things it does to get the name reliably. Call this function, and it will get you the file name that is passed in the system call.

-1
votes

Your pointer here:

current_pt_regs()->di;

Example:

printk("%s\n", (char *)current_pt_regs()->di);