As far as I know, when we want to access a stack segment, the DPL of the descriptor should be equal to
max(RPL,CPL)
where RPL is of the SS segment register, and CPL means current privilege level.
So can we access an underprivileged stack by weakening our CPL with the RPL? For example, CPL=0, RPL=3 for the SS segment register. So we should be able to access the stack of PL 3. Is it true?
No.
Section 5.7 of the Intel SDM is clear
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.
The rationale is that privileged code cannot afford to share a stack with unprivileged code for security reasons - each privilege has its own stack as defined in the TSS.
You can access the stack with a data segment register (e.g. through ds
), in that case one must have max(CPL, RPL) <= DPL (weakened CPL is still more or equally privileged as the DPL of the segment).