clinux-kernelkernel-modulekernelrootkit

EFAULT from function in kernel module


I am trying to compare if two filenames refer to the same file by checking if their inode and device IDs match. Currently, I call vfs_stat to obtain the IDs.

The problem is, if I pass vfs_stat a filename that's stored in userspace, it works fine, but if I pass it a filename that's stored in as a global variable in my kernel module, it errors with EFAULT

Is there any other way to obtain the IDs or compare if two files are the same?


Solution

  • vfs_stat takes a filename stored in userspace. But if you trace that call in the source, you'll see (in fs/stat.c) that there are basically two parts. Lookup the struct path from the userspace filename string, then call the VFS stat operation based on the contents of the path struct. So you can do the same from kernel space. Look into kern_path() to look up the struct path for a filename stored in kernel space. From there, you can call vfs_getattr() directly. Don't forget to path_put when you're done.

    Basically, you're using the important bits of vfs_fstatat(). But also consider if you can manage without the stat call. There's an inode pointer somewhere inside the path struct, and that might be good enough for what you're trying to do.