1

I want to know how privilege separation is enforced by the kernel and the part of kernel that is responsible for this task.

For example, assume there are two processes running -- one at ring 0 and another at ring 3. How does the kernel keep track of the ring number of each process?

Edit: I know about ring numbers. My question is about the part of kernel (module or something) which performs checks on the processes to find out their privilege level. I believe there might be a component of kernel which would check the ring number of a process.

cout_display_name
  • 313
  • 1
  • 2
  • 14
  • Possible duplicate of [What are Ring 0 and Ring 3 in OS](http://stackoverflow.com/questions/18717016/what-are-ring-0-and-ring-3-in-os) – David C. Rankin Aug 14 '16 at 08:33
  • Possible duplicate of [**What are Ring 0 and Ring 3 in OS**](http://stackoverflow.com/questions/18717016/what-are-ring-0-and-ring-3-in-os). Beyond the possible duplicate, this question is only tangentially a programming question, and seems more of a *Kernel Documentation* question. – David C. Rankin Aug 14 '16 at 08:35
  • Wait. Aren't rings checked by the **hardware**? When we say that a process runs in Ring 3 we literally mean that the CPU is set to execute at that level. The OS switches the CPU mode before letting a program run, and when it is called again the interrupt switches the CPU back to ring 0 and let the OS do its thing. So to answer your question: there isn't a module of the kernel that checks this because it's the *hardware* that does that. The kernel, in particular the scheduler, switches ring just before executing user code and that's all. – Bakuriu Aug 14 '16 at 09:08
  • @Bakuriu I just found out that the CPU has Current Privilege Level (CPL) field in code segment register which can be set only by instructions that alter the flow of program execution, like call. Can you please explain how this field is set? – cout_display_name Aug 14 '16 at 09:30

1 Answers1

4

There is no concept of a ring number of a process.

The kernel is mapped in one area of memory, userspace is mapped in another. On boot the kernel specifies an address where the cpu has to jump to when the syscall instruction is executed. So someone does syscall, the cpu switches to ring0 and jumps to the address as instructed by the kernel. It is now executing kernel code. Then, on return, the cpu switches back to ring3 and resumes execution.

Similar story for other ways of entering the kernel like exceptions.

So, how does linux kernel enforce separation? It sets things up for usersapace to execute in ring3. Anything triggering the cpu to switch to ring0 also makes the jump to an address configured by the kernel on boot. no code other than kernel code executes in ring0

  • Thanks for the answer. My assumption was wrong and you explained it clearly. – cout_display_name Aug 14 '16 at 14:50
  • So now I know that it's the CPU which is executing at either ring 0 or ring 3. Hence, there should be a SW component that sets CPU's execution level, right? – cout_display_name Aug 14 '16 at 14:53
  • 1
    Depending on what happens you can get back to userspace with sysret or iret. There are several ways of making the cpu switch to ring0. I don't see why would you want to drill into it. This goes beyond fundamental concepts shown on the example of amd64 and goes into crap details of little to no value unless you work on this stuff. I suggest you read on operating system instead, the classic book is "Unix internals: the new frontiers". –  Aug 14 '16 at 18:04