【发布时间】:2012-08-17 00:05:02
【问题描述】:
我正在编写一个可以访问特定进程内存的内核模块。我用do_mmap()对一些用户空间内存做了匿名映射:
#define MAP_FLAGS (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS)
prot = PROT_WRITE;
retval = do_mmap(NULL, vaddr, vsize, prot, MAP_FLAGS, 0);
vaddr和vsize设置较早,调用成功。在我从内核模块(通过copy_to_user)写入该内存块之后,我想删除它的PROT_WRITE 权限(就像我在普通用户空间中使用mprotect 一样)。我似乎找不到允许这样做的函数。
我尝试取消映射该区域并使用正确的保护重新映射它,但这会将内存块清零,擦除我刚刚写入的所有数据;设置 MAP_UNINITIALIZED 可能会解决这个问题,但是,从手册页:
MAP_UNINITIALIZED(自 Linux 2.6.33 起)
不要清除匿名页面。此标志旨在提高嵌入式性能 设备。只有在内核配置了 CONFIG_MMAP_ALLOW_UNINITIALIZED 选项。由于安全隐患,该选项 通常仅在嵌入式设备上启用(即,已完成 控制用户内存的内容)。
所以,虽然这可能会满足我的要求,但它的便携性并不高。有没有标准的方法来完成我的建议?
【问题讨论】:
-
为什么哦,为什么要在内核模块中做所有这些事情?有了明确定义的 API,用户空间进程本身就没有理由不能完成。
-
@mpe 我在用户空间做不到的原因是我正在写的模块是一个进程加载器;我对用户空间代码没有任何影响。
-
进程加载器是什么意思?您是说 binfmt 处理程序吗?
-
@mpe 是的,它是一个 binfmt 处理程序。
-
有什么理由你不能在用户空间加载并使用 binfmt_misc 让它看起来内核正在直接加载你的程序? (参见文档/binfmt_misc.txt)
标签: memory-management process linux-kernel mmap