Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.
  • What would happen if a kernel-level process sets some of its memory pages as PROT_NONE with mprotect and another kernel-level process tries to read one of these protected pages?
  • What is the equivalent of mprotect in windows? What are the main differences?
share|improve this question

1 Answer 1

up vote 2 down vote accepted

It depends on what you mean by "kernel process".

In Linux, each process has its own address space, which is embodied by the MMU and its configuration table. Roughly speaking, at any one time, the MMU is configured to find information about pages (where each page from the address space is in RAM, if it is present at all, and the access rights) in tables located at some address in physical RAM (details vary depending on the architecture, but in 32-bit x86 the CR3 register is used for that). When the CPU switches from one process to another, it changes that configuration (i.e. before granting control to any process, the CPU loads the CR3 register with the right value for that process). mprotect() is the API provided by the kernel to applications (along with mmap()) to modify these tables. It is important to note that the mapping is many-to-one: each page in the address space is mapped to a physical page (or to "none"), but several pages in the address space can point to the same physical page, with access rights which need to be equal.

This means that if a process uses mprotect(), then it modifies its own set of MMU tables, and the other processes are unaffected. If a process alters the access rights to PROT_NONE for a page it sees, and some other process also sees the same physical page in its own address space (through some shared memory setup), then the second process can still access the page.

Note that when a process does a system call, the CPU jumps into the kernel space and obtains kernel-level privileges, but the MMU is not affected (well, in fact it can be, depending on the architecture and kernel version; normally, each page is mapped twice, with one mapping accessible only with kernel privileges, so that the kernel may write into RAM which is, from the point of view of the process, absent or read-only; however, things can become a bit more complex on 32-bit x86 because the double-mapping implies a restriction to at most 2 GB of address space per process, and recent kernels have some tricks to go to 4 GB per process, basically by switching MMU mappings when entering the kernel; let's not confuse the situation any further with such details). So the code for the system call executes with the mapping as the calling process sees it (albeit with kernel privileges).

Kernel threads, sometimes known as kernel processes, are something different. These are processes without RAM. They run with kernel-level privileges and occupy a slot in the scheduler, but they don't have an address space of their own. Being threads, they are occasionally granted the CPU (that's the point). However, since they don't have an address space, they don't incur a MMU table switch when they are activated, which is a blessing because MMU table switches are expensive (because of TLB flushes). So kernel threads basically run in the address space of whatever normal process was last running.

If a kernel thread does a mprotect() on a page, assuming that this works at all (the Linux kernel may have safeguards here, I haven't tried), then it will modify the current address space, the one of the unlucky process who ran last, and which process is that cannot be reliably predicted. Whether this impacts another kernel process depends on whether that other process will use the same address space or not, something which can change at each context switch, hundreds of times per second.

Moreover, kernel threads run with kernel privileges, which means that they can do more than normal applications. They tend to be able to read PROT_NONE pages, provided that they do so through the right address (there again, it depends on the architecture and kernel version, but kernel threads will normally be able to see all pages with full access rights for them).

Summary: if it is allowed at all by the kernel, it seems most unwise to fiddle with userland RAM from kernel threads.

share|improve this answer
    
So, imagine I have a program running with kernel privileges. Could other program, with the same privileges, use for instance ptrace() to see the memory of the first program, even the PROT_NONE protected pages? –  eversor Jul 3 '13 at 21:51
    
Kernel privileges are everything. When you have kernel privileges, you can do whatever you want with the machine. This include reading and modifying the full contents of RAM, replacing the kernel itself with some other code, issuing arbitrary commands to all hardware elements... –  Tom Leek Jul 3 '13 at 21:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.