chengzi@blog:/posts$ cat /posts/x86-privileges.md
区分 x86 中 CPL/RPL/DPL 特权级别

区分 x86 中 CPL/RPL/DPL 特权级别

Date
2024-05-24
Tags
x86 os
Description
这篇文章简要区分一下 x86 不同特权级别的作用。

之前总觉得 x86 特权级校验的规则很难记住,但是今天归纳了一下发现其机制非常简单。

选择子和描述符

在进入正题之前,首先说一说选择子和描述符。

段描述符表示是一个段的地址映射、权限、以及其他的属性。

除此以外,还有门描述符、TSS描述符等,他们都保存在DT表里面,DT表基地址保存在DTR寄存器中(比如GDTR、LDTR)。

描述符本身通常并不随当前进行的任务而发生变化,他记录被访问对象的属性。

而选择子指向一个描述符,除此以外,还记录访问者的属性。

保护了什么

保护模式到底保护了什么?一句很简单的话就是:

被访问对象要被比他权限更高(或者相等)的访问者所访问。

这句话很简单,而且理解了这句话,就理解这三个特权级别的区别。

RPL

RPL,全称是 Requested Privilege Level,其位于段选择子上,表示访问者访问该描述符所具有的权限

DPL

DPL,全称是 Descriptor Privilege Level,听名字就知道其位于描述符上,表示被访问对象的权限

一个例子

下面举个违背保护规则的例子,比如我有一条指令 mov rax, qword ptr es:[6400H] 想访问 es 段的内存,此时,es 段选择子的RPL 是 Ring2,但是 es 段描述符 (被访问内容)是 Ring1,就违法了上一节所说的规则,就会触发 CPU 的保护异常 (Protection Fault)。

CPL

作为这三个缩写词中最常见的词,为什么最后说CPL呢?其实在 x86 当中,CPL 只是一种特殊的 RPL,他就是 CS 段以及 SS 段的RPL。(为什么CS和SS放在一起呢,因为通常来说当前指令和栈都是和当前任务密切相关的,并且通过门进行调用时,会自动从 TSS 段中取出新的 SS 值。所以 CS 和 SS 段是放在一起说的。)

而执行代码时,本质是对 cs:rip 处的内存进行访问,权限检查也和上面类似,取 cs 的RPL (或者说是CPL)和 段描述符的 DPL 进行比较。

保护规则的补充

定义了 CPL 之后,就可以对上面的规则进行补充了,如下图所示:

protection

在访问一个段时,需要:

  1. CPL <= DPL
  2. RPL <= CPL

只有当这两个条件同时满足时,才能访问成功。否则就会触发保护异常。