Take the 2-minute tour ×

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():


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?

share|improve this question
Why oh why are you doing all that in your kernel module? With a sanely defined API there's no reason that couldn't be done by the userspace process itself. –  mpe Aug 17 '12 at 12:13
@mpe The reason I can't do it in user space is that the module I'm writing is a process loader; I don't have any influence over the user space code. –  nosuchthingasstars Aug 17 '12 at 12:31
What do you mean by process loader? Do you mean a binfmt handler? –  mpe Aug 17 '12 at 15:33
@mpe Yes, it's a binfmt handler. –  nosuchthingasstars Aug 17 '12 at 15:34
Is there any reason you can't do the loading in userspace and use binfmt_misc to make it appear that the kernel is directly loading your program? (see Documentation/binfmt_misc.txt) –  mpe Aug 20 '12 at 3:52
show 1 more comment

2 Answers

up vote 1 down vote accepted

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.

share|improve this answer
add comment

In userspace there is a system call mprotect that can modify the protection flags on existing mapping. You probably need to follow from the implementation of that system call, or maybe simply call it directly from your code. See mm/protect.c.

share|improve this answer
add comment

Your Answer


