是否可以从 inotify 子系统中转储 inode 信息?
Is it possible to dump inode information from the inotify subsystem?
我想知道我的编辑器正在查看哪些文件。
我了解到 count /proc/${PID}/fd
中的 inotify fds 的数量是可能的,我的问题是:Is it possible to dump the list of watched inode by一个进程?
更新:
我已经更新了一个可行的解决方案,感谢您提供有用的参考 here。
更新 2:好吧,最近我发现 kallsyms_lookup_name
(以及更多符号)自 Linux Kernel v5.7
以来没有导出,所以如果有人关心,我决定更新我自己的解决方案。
已解决。
借助 khook 中使用的 kprobe
机制,我只是简单地挂钩 __x64_sys_inotify_add_watch
并使用 user_path_at
窃取 dentry
.
下面列出了代码片段,并提供了我的工作解决方案here。
#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
//regs->(di, si, dx, r10), reference: arch/x86/include/asm/syscall_wrapper.h#L125
//SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, u32, mask)
KHOOK_EXT(long, __x64_sys_inotify_add_watch, const struct pt_regs *);
static long khook___x64_sysinotify_add_watch(const struct pt_regs *regs)
{
int wd;
struct path path;
unsigned int flags = 0;
char buf[PATH_MAX];
char *pname;
// decode the registers
int fd = (int) regs->di;
const char __user *pathname = (char __user *) regs->si;
u32 mask = (u32) regs->dx;
// do the original syscall
wd = KHOOK_ORIGIN(__x64_sys_inotify_add_watch, regs);
// get the pathname
if (!(mask & IN_DONT_FOLLOW))
flags |= LOOKUP_FOLLOW;
if (mask & IN_ONLYDIR)
flags |= LOOKUP_DIRECTORY;
if ( wd>=0 && (user_path_at(AT_FDCWD, pathname, flags, &path)==0) )
{
pname = dentry_path_raw(path.dentry, buf, PATH_MAX); //"pname" points to "buf[PATH_MAX]"
path_put(&path);
printk("%s, PID %d add (%d,%d): %s\n", current->comm, task_pid_nr(current), fd, wd, pname);
}
return wd;
}
我想知道我的编辑器正在查看哪些文件。
我了解到 count /proc/${PID}/fd
中的 inotify fds 的数量是可能的,我的问题是:Is it possible to dump the list of watched inode by一个进程?
更新: 我已经更新了一个可行的解决方案,感谢您提供有用的参考 here。
更新 2:好吧,最近我发现 kallsyms_lookup_name
(以及更多符号)自 Linux Kernel v5.7
以来没有导出,所以如果有人关心,我决定更新我自己的解决方案。
已解决。
借助 khook 中使用的 kprobe
机制,我只是简单地挂钩 __x64_sys_inotify_add_watch
并使用 user_path_at
窃取 dentry
.
下面列出了代码片段,并提供了我的工作解决方案here。
#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
//regs->(di, si, dx, r10), reference: arch/x86/include/asm/syscall_wrapper.h#L125
//SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, u32, mask)
KHOOK_EXT(long, __x64_sys_inotify_add_watch, const struct pt_regs *);
static long khook___x64_sysinotify_add_watch(const struct pt_regs *regs)
{
int wd;
struct path path;
unsigned int flags = 0;
char buf[PATH_MAX];
char *pname;
// decode the registers
int fd = (int) regs->di;
const char __user *pathname = (char __user *) regs->si;
u32 mask = (u32) regs->dx;
// do the original syscall
wd = KHOOK_ORIGIN(__x64_sys_inotify_add_watch, regs);
// get the pathname
if (!(mask & IN_DONT_FOLLOW))
flags |= LOOKUP_FOLLOW;
if (mask & IN_ONLYDIR)
flags |= LOOKUP_DIRECTORY;
if ( wd>=0 && (user_path_at(AT_FDCWD, pathname, flags, &path)==0) )
{
pname = dentry_path_raw(path.dentry, buf, PATH_MAX); //"pname" points to "buf[PATH_MAX]"
path_put(&path);
printk("%s, PID %d add (%d,%d): %s\n", current->comm, task_pid_nr(current), fd, wd, pname);
}
return wd;
}