The k project

Jump to userland

Description

Once you’ve loaded the binary into memory, with separate segment for code and data, you should be able to execute the rom code. This code should run in ring3, so it means that it should be unprivileged.

The processor state needed in order to launch an unprivileged program is the following:

Register State
ds DS_USER | RING3_DPL
es DS_USER | RING3_DPL
ss SS_USER | RING3_DPL
esp SS_USER upper address
eflags Enable interrupts
cs CS_USER | RING3_DPL
eip Linear rom entry point

According to the intel manual:

Privilege level checking also occurs when the SS register is loaded with the
segment selector for a stack segment.  Here all privilege levels related to the
stack segment must match the CPL; that is, the CPL, the RPL of the stack-
segment selector, and the DPL of the stack-segment descriptor must be the same.
If the RPL and DPL are not equal to the CPL, a general-protection exception
(#GP) is generated.

It implies that we must change the cs and ss privilege at the same time.

Therefore, we shall use the iret instruction to jump to userland. With a hand-crafted stack, iret sets every register aforementioned except ds and es so we must set them beforehand.

Possible bug causes

So be sure to test every part of your kernel before jumping to userland.