`
Ydoing
  • 浏览: 105968 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

不同特权级代码段之间的跳转(CPL DPL RPL之间的关系)

 
阅读更多

1、特权级
2、一致代码段和非一致代码段
3、DPL、RPL、CPL分别代表的含义,存储在什么位置,以及它们之间的关系
4、不同特权级数据段之间的访问规则
5、不同特权级代码段之间的转移
6、代码段之间的转移对堆栈的影响
7、结合pmtest5.asm来见证不同特权级代码段之间的跳转

一、特权级
在IA32的分段机制下,特权级总共有4个特权级别,从高到低分别是0、1、2、3。数字越小表示的特权级越大。特权级如下图所示:


较为核心的代码和数据,将被存放在特权级较高的层级中。处理器将用这样的机制来避免低特权级的任务在不被允许的情况下访问位于高特权级的段。

二、一致代码段 和 非一致代码段
系统要安全,必须保证内核与用户程序分离开,内核要安全,必须不能被用户来打扰。但是有的时候,用户程序也是需要访问内核中的部分数据,那怎么办?

于是操作系统就将内核中的段分为共享的代码段和非共享的代码段两部分。
其中一致代码段就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接访问的代码。
一致代码段的限制作用:
(1)特权级高的代码段不允许访问特权级低的代码段:即内核态不允许调用用户态下的代码。
(2)特权级低的代码段可以访问特权级高的代码段,但是当前的特权级不发生变化。即:用户态可以访问内核态的代码,但是用户态仍然是用户态。

非一致代码段:为了避免低特权级的访问而被操作系统保护起来的系统代码,也就是非共享代码。
非一致代码段的限制作用:
(1)只允许同特权级间访问
(2)绝对禁止不同级间访问,即:用户态不能访问内核态,内核态也不访问用户态。

下图为一致码段与非一致码段的访问规则:


三、CPL、DPL、RPL分别代表的含义,存储在什么位置,以及它们之间的关系
1、CPL(Current Privilege Level)是当前执行的程序或任务的特权级。它被存储在CS和SS的第0位和第1位上。通常情况下,CPL等于代码的段的特权级。在遇到一致代码段时,一致代码段可以被相同或者更低特权级的代码访问。当处理器访问一个与CPL特权级不同的一致代码段时,CPL不会被改变。

2、DPL(Descriptor Privilege Level):DPL表示段或者门的特权级,它被存储在段描述符或者门描述符的DPL字段中。当当前代码段试图访问一个段或者门时,DPL将会和CPL以及段或门选择子的RPL相比较,根据段或者门类型的不同,DPL将会被区别对待,下面介绍一下各种类型的段或者门的情况。
(1)数据段:DPL规定了可以访问此段的最低特权级。比如,一个数据段的DPL是1,那么只有运行在CPL为0或者1的程序才有权访问它。
(2)非一致代码段(不使用调用门的情况下):DPL规定访问此段的特权级。比如一个非一致代码段的特权级为0,那么只有CPL为0的程序才可以访问它。
(3)调用门:DPL规定了当前执行的程序或任务可以访问此调用门的最低特权级(这与数据段的规则是一致的)。
(4)一致代码段和通过调用门访问的非一致代码段:DPL规定了访问此段的最高特权级。比如,一个一致代码段的DPL是2,那么CPL为0和1的程序将无法访问此段。

3、RPL(Requested Privilege Level):RPL是通过选择子的第0位和第1位表现出来的。处理器通过检查RPL和CPL来确认一个访问请求是否合法。

四、不同特权级数据段之间的访问规则
数据段中DPL规定了可以访问此段的最低特权级,因此,对数据的访问,只要CPL和RPL都小于被访问的数据段的DPL就可以了,即CPL<=DPL和RPL<=DPL。

五、不同特权级代码段之间的转移
使用jmp或call指令可以实现下列4种转移
(1)目标操作数包含目标代码段的段选择子。
(2)目标操作数指向一个包含目标代码段选择子的调用门描述符。
(3)目标操作数指向一个包含目标代码段选择子的TSS。
(4)目标操作数指向一个任务门,这个任务门指向一个包含目标代码段选择子的TSS。
这4种方式可以看做是两大类,一类是通过jmp和call的直接转移(上述第一种),另一类是通过某个描述
符的间接转移(上述第2,3,4种)。

1、通过jmp或call进行直接转移


2、通过调用门进行转移
(1)门描述符的结构

调用门描述符里面保存着目标代码段的段选择子,偏移量,以及属性。


(2)调用门的使用方式


假设我们想由代码A转移到代码B,运用一个调用门G,即调用门G中的目标选择子指向代码B的段。实际上,这个问题主要涉及这几个元素:CPL、RPL、代码B的DPL(记做DPL_B),调用门G的DPL(记做DPL_G)。
调用门使用时特权级检验的规则如下:


也就是说,通过调用门和call指令,可以实现从低特权级到高特权级的转移,无论目标代码段时一致的还是非一致的。
通过调用门和jmp指令,如果目标代码段是一致的,则可以实现从低特权级到高特权级的转移。如果目标代码段是非一致的,则只能实现相同特权级的转移。

六、代码段之间的转移对堆栈的影响

1、“长”跳转/调用 和 “短”跳转/调用
如果一个调用或跳转指令时段间而不是段内进行的,那么我们称之为“长”的(Far jmp/call),反之,如果在段内则是“短”的(Near jmp/call)。

那么长的和短的jmp或call有什么分别呢?
对于jmp而言,仅仅是结果不同罢了,短跳转对应段内,长跳转对应段间。
对于call来说,就比较复杂一些,因为call指令是会影响堆栈的,长调用和短调用对堆栈的影响是不同的。

下面我们讨论短调用对堆栈的影响,call指令执行时下一条指令的eip压栈,到ret指令执行时,这个eip会被从堆栈中弹出,
如下图所示:


这是短调用的情况。

下面我们讨论长调用对堆栈的影响,call指令执行时会将调用者的cs和eip压栈,到ret指令执行时,这个eip和cs会被从堆栈中弹出,如下图所示:


2、有特权级变换的转移对堆栈的影响
在不同特权级下的堆栈段不同,所以每一个任务最多可能在4个特权级间转移,所以,每个任务实际上需要4个堆栈。可是我们只有一个ss和一个esp,那么当发生堆栈切换,我们该从哪里获得其余堆栈的ss和esp呢?
解决这个问题,需要一个数据结构TSS(Task-State Stack),如图:


当堆栈发生切换时,内层的ss和esp就是从这里取得的,比如,我们当前所在的是ring3,当转移至ring1时,堆栈将被自动切换到由ss1和esp1指定的位置。由于只是在由外层转移到内层(低特权级到高特权级)切换时新堆栈才会从TSS中取得,所以TSS中没有位于最外层的ring3的堆栈信息。
下面让我们来看看整个的转移过程是怎么样的?

执行call前后堆栈段的变化:


(1)根据目标代码段的DPL(新的CPL)从TSS中选择应该切换至哪个ss和esp
(2)从TSS中读取新的ss和esp。在这过程中如果发现ss、esp或者TSS界限错误都会导致无效TSS异常
(3)对ss描述符进行检验,如果发生错误,同样产生#TS异常
(4)暂时性地保存当前ss和esp的值
(5)加载新的ss和esp
(6)将刚刚保存起来的ss和esp的值压入新栈
(7)从调用者堆栈中将参数复制到被调用者堆栈(新堆栈)中,复制参数的数目由调用门中Param Count一项来决定。
(8)如果Param Count是零的话,将不会复制参数。
(9)将当前的cs和eip压栈
(10)加载调用门中指定的新的cs和eip,开始执行被调用者过程。

执行ret前后堆栈段的变化:


(1)检查保存的cs中的RPL以判断返回时是否要变换特权级
(2)加载被调用者堆栈上的cs和eip(此时会进行代码段描述符和选择子类型和特权级检验)
(3)如果ret指令含有参数,则增加esp的值以跳过参数,然后esp将指向被保存过的调用者ss和esp。注意,ret的参数必须对应调用门中的Param Count的值
(4)加载ss和esp,切换到调用者堆栈,被调用者的ss和esp被丢弃。在这里将会进行ss描述符、esp、以及ss段描述符的检验
(5)如果ret指令含有参数,增加esp的值以跳过参数(此时已经在调用者堆栈中)
(6)检查ds、es、fs、gs的值,如果其中哪一个寄存器指向的段的DPL小于CPL(此规则不适合于一致代码段),那么一个空描述符会被加载到该寄存器中。
综上所述,使用调用门的过程实际上分为两部分,一部分是从低特权级到高特权级,通过调用门和call指令来实现;另一部分则是从高特权级到低特权级,通过ret指令来实现.

分享到:
评论

相关推荐

    操作系统篇-调用门与特权级(CPL、DPL和RPL).docx

    当程序从一个代码段转移到另一个具有不同特权级的代码段时,处理器会自动更新CPL。 - **DPL(Descriptor Privilege Level)**:表示段描述符或门描述符的特权级。DPL被存储在描述符的DPL字段中。当当前代码段尝试...

    intel DPL RPL详解

    访问数据段或堆栈段时,默认使用CPU和RPL中的最小特权级去访问数据段,因此max{CPL, RPL} ≤ DPL,否则访问会被拒绝。 **2. 代码段访问** - **转跳规则**:所有程序转跳中,CPU不会将段选择子的RPL赋给转跳后程序...

    [自制操作系统] 第10回 认识保护模式之深入浅出特权级.doc

    然而,当用户程序试图访问数据段时,DS寄存器的RPL会被设置为用户进程的CPL(通常是3),此时若数据段的DPL为0,根据特权级检查规则(CPL≤DPL且RPL≤DPL),访问将被拒绝,因为RPL为3无法满足条件。 门结构在特权...

    第6章 从内核态到用户态1

    数据段和栈段的访问需要满足DPL与CPL的关系,代码段的一致性和非一致性则决定了其可被哪些特权级访问。 从内核态到用户态,或者反之,需要进行特权级转移。低特权级向高特权级的转移通常通过中断或系统调用来实现,...

    国科大操作系统高级教程-思考题(更新之2023.10.24)

    体现:1)在GDT、LDT及IDT中,均有自己界限,特权级等属性,这是对描述符所描述的对象的保护2)在不同特权级间访问时,系统会对CPL、RPL、DPL、IOPL等进行检验,对不同层级的程序进行保护,同还限制某些特殊指令的...

    Window s 中段页式内存管理硬件实现剖析

    最后根据特权级规则,只有当 Max(CPL, RPL) ≤ DPL 时,才允许访问该段,否则产生异常 13。 Window s 操作系统在 80x86CPU 中的内存管理单元(MMU)的硬件工作原理,实现了内存单元的段页式寻址、保护检查和虚拟...

    2021操作系统高级教程思考题.docx

    - 在不同特权级间的访问时,系统会对 CPL、RPL、DPL、IOPL 等进行检查,保护不同层级的程序,并限制某些特殊指令的使用。 - 分页机制通过 PDE 和 PTE 中的 R/W 和 U/S 等属性提供了页级别的保护,同时也通过将线性...

    操作系统高级教程.docx

    特权级(CPL、RPL、DPL、IOPL)用于限制不同级别程序的权限,防止误操作。分页机制也有保护作用,通过页表的权限位(如R/W、U/S)来控制对内存页面的访问,确保数据的安全。 6. **两次设置GDT的原因**: 在`setup`...

    龚伦强内核过游戏驱动保护教程

    - **定义**:调用门是一种特殊的系统描述符,用于实现不同特权级之间的调用。 - **特点**: - 粒度标志(G):决定段限长是以字节还是以4KB为单位。 - AVL:保留位,用于系统软件的某些特定功能。 - 21位:保留位...

    2019年复习重点范围1

    数据访问的保护规则规定,DPL(描述符特权级)必须大于等于MAX(CPL, RPL),其中CPL是当前程序的特权级,RPL是请求特权级。段间调用或跳转时,需要考虑限长和特权级的比较,以确保安全的代码执行。 【指令系统】 ...

    计算机实模式与保护模式

    保护模式还引入了权限级别的概念,包括RPL(Request Privilege Level)、CPL(Current Privilege Level)、DPL(Descriptor Privilege Level)等,这些级别确保了不同级别的程序只能访问相应级别的资源,从而提高了...

    软件安全原理.pdf

    2. **特权级管理**:通过CPL(Current Privilege Level)、DPL(Descriptor Privilege Level)、RPL(Requested Privilege Level)等机制实现权限控制。 3. **宏内核与微内核**: - **宏内核**:所有核心功能都在...

Global site tag (gtag.js) - Google Analytics