特权级及其特权级转移

1 CPL/DPL/RPL

  • DPL(Descriptor Privilege Level)
    指GDT或LDT描述符中的DPL字段,根据段的类型不同其处理规则而异:
    • 数据段:指定了访问该数据段的最低特权级(如DPL为1的数据段,只有特权级 0 和 1 下才能访问。
    • 非一致代码段:规定了只有在特权级等于 DPL 时才能访问。
    • 一致代码段和通过调用门访问非一致代码段:规定只有在特权级等于或高于 DPL的情况下才能访问
    • TSS 段:规定了访问此段的最低特权级,与数据段一致。
  • CPL(current privilege level)
    指当前执行任务或程序代码段寄存器(CS)或堆栈寄存器(SS)中第 0 位和第 1 位的值。此一般等于程序和任务的代码所在段的 DPL。注意:当跨特权级访问一致代码段时,此时CPL与访问者一致,不会与此一直代码段DPL相等。
  • RPL(Requested privilege Level)
    指程序或任务所在段所对应的选择子的第0位和第 1 位所代表的值。处理器比较 RPL 和 CPL 来判断是否为一个合法访问,即选择 CPL 与 RPL 较大的值来判定是否有权执行某一访问动作。RPL可以很好的限制用户态程序对于内核态内存的访问。用户态程序执行系统调用或中断等转移到内核态执行时,在内核态执行时的RPL由调用者使用的选择子来决定,从而保证了用户态执行时的 RPL 仍然是用户态权限,所能访问的内存仍仅限于用户态内存。

2 不同特权级代码段之间的转移

特权级是以段为单元来划分的,故特权级的转移必然伴随着代码段之间的跳转。程序从一个代码段跳转到另外一个代码段之前,目标代码段的选择子会加载到 cs 中。但是在加载的过程中,系统会根据当前现状进行特权级、类型、代码段界限等进行检查,若检查通过,则进行跳转。

程序控制权的转移可通过指令 jmp、call、int, ret, sysenter、sysexit、iret等,也可由硬中断和异常引起。

使用jmp 和call 实现以下 4 种转移:

  1. 目标操作数包含目标代码段的选择子
  2. 目标操作数指向一个包含目标代码段选择子的调用门描述符
  3. 目标操作数指向一个包含目标代码段选择子的TSS
  4. 目标操作数指向一个任务门,这个任务门指向一个包含目标代码段选择子的TSS

2.1 通过jmp 或 call 进行直接转移

  • 如果目标是非一致代码段,要求CPL必须等于目标段的DPL,同时要求RPL小于等于DPL。
  • 如果目标是一致代码段,则要求CPL大于或等于目标段的DPL,RPL此时不做检查。当转移到一致代码段后,CPL会被延续下来,而不会变成目标代码段的DPL。

2.2 call调用时的堆栈变化

  • 短调用时的堆栈变化
    call时:
特权级及其特权级转移_第1张图片

ret时:

特权级及其特权级转移_第2张图片
  • 同特权级段间跳转
    call:
特权级及其特权级转移_第3张图片

ret:

特权级及其特权级转移_第4张图片
  • 不同特权级段间跳转
    call:
特权级及其特权级转移_第5张图片

ret:

特权级及其特权级转移_第6张图片

你可能感兴趣的:(特权级及其特权级转移)