【发布时间】:2018-01-26 11:45:01
【问题描述】:
我正在使用 linux 内核中的 kprobes 挂钩一些系统调用。在此期间,我想使用mmap 读取文件。
无法在内核内部使用系统调用,但通常有其他方法可以绕过它。 (例如 sys_open 与 vfs_read)。
这可能吗?如果可以,怎么做?
【问题讨论】:
-
mmap 在调用进程的虚拟地址空间中创建一个新映射,因为我们在内核中没有任何进程,所以让它工作起来真的很棘手。另一方面,为什么不直接在内核中打开并读取它(filp_open/vfs_read)?
-
static int file_write(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size) { mm_segment_t oldfs;诠释; oldfs = get_fs(); set_fs(get_ds()); ret = vfs_write(文件、数据、大小、&offset); set_fs(oldfs);返回 ret; } static int file_read(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size) { mm_segment_t oldfs;诠释; oldfs = get_fs(); set_fs(get_ds()); ret = vfs_read(file, (void __force __user *)data, size, &offset); set_fs(oldfs);返回 ret; }
-
如果我正确理解了内核的内部工作原理,那么就会有一个进程,因为我正在挂钩系统调用。所以我所有的代码都在一个进程中运行。感谢您的代码。
vfs_read确实是一个替代方案,但mmap'ed文件可以更好地与我现有的代码一起使用,并且我可以避免复制一些内存。 -
为了我的澄清,内核 mmap/filp_open 会返回一个位于内核空间的指针,如何避免复制一些内存?
-
只是又想了一个办法(我没试过,但很好奇它是否有效!),在内核中分配一些物理内存,然后将其传递给 do_mmap() 并检查返回值,如果成功,请不要使用返回的地址,而是使用您为 do_mmap() 调用传递的地址来访问文件。唯一的缺点是如果文件很大,你将不得不分配大的物理内存。
标签: linux kernel memory-mapping