从内核模块更改用户空间内存保护标志(Change user space memory protection flags from kernel module)

编程入门 行业动态 更新时间:2024-10-27 12:24:04
内核模块更改用户空间内存保护标志(Change user space memory protection flags from kernel module)

我正在编写一个可以访问特定进程内存的内核模块。 我用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选项配置了内核,才能使用该标志。 由于安全隐患,该选项通常仅在嵌入式设备(即,用户可完全控制用户内存内容的设备)上启用。

所以,虽然这可能做我想要的,但它不会很便携。 有没有一个标准的方法来完成我所建议的?

I am writing a kernel module that has access to a particular process's memory. I have done an anonymous mapping on some of the user space memory with 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 and vsize are set earlier, and the call succeeds. After I write to that memory block from the kernel module (via copy_to_user), I want to remove the PROT_WRITE permission on it (like I would with mprotect in normal user space). I can't seem to find a function that will allow this.

I attempted unmapping the region and remapping it with the correct protections, but that zeroes out the memory block, erasing all the data I just wrote; setting MAP_UNINITIALIZED might fix that, but, from the man pages:

MAP_UNINITIALIZED (since Linux 2.6.33)

Don't clear anonymous pages. This flag is intended to improve performance on embedded devices. This flag is only honored if the kernel was configured with the CONFIG_MMAP_ALLOW_UNINITIALIZED option. Because of the security implications, that option is normally enabled only on embedded devices (i.e., devices where one has complete control of the contents of user memory).

so, while that might do what I want, it wouldn't be very portable. Is there a standard way to accomplish what I've suggested?

最满意答案

经过一些更多的研究后,我发现了一个名为get_user_pages()的函数get_user_pages()我发现最好的文档在这里 ),它返回给定地址的用户空间页面列表,该地址可以用kmap()映射到内核空间并写入方式(在我的情况下,使用kernel_read() )。 这可以用作copy_to_user()的替代品,因为它允许在检索到的页面上强制写入权限。 唯一的缺点是你必须一页接一页地写,而不是一页一页,但它确实解决了我在我的问题中描述的问题。

After some more research, I found a function called get_user_pages() (best documentation I've found is here) that returns a list of pages from userspace at a given address that can be mapped to kernel space with kmap() and written to that way (in my case, using kernel_read()). This can be used as a replacement for copy_to_user() because it allows forcing write permissions on the pages retrieved. The only drawback is that you have to write page by page, instead of all in one go, but it does solve the problem I described in my question.

更多推荐

本文发布于:2023-08-07 23:08:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1466376.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:内核   模块   标志   内存   用户

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!