一致码段、非一致码段、dpl、cpl和rpl简介

一、一致码段和非一致码段

操作系统保护模式下把代码段非为一致代码段和非一致代码段的原因是:内核程序和用户程序要分开,内核程序不能被用户程序干扰。但是有时候用户程序也需要读取内核的某些数据,于是操作系统就从内核程序中分配一些可以供用户程序访问的段,但是不允许用户程序写入数据,用户程序访问这些段时遵守以下规则:
1、内核程序不知道用户程序的数据,不调用用户程序的数据,也不转移到用户程序中来。
2、用户程序只能访问到内核的某些共享段,这些段称为一致代码段
3、用户程序不能访问内核不共享的段

一致代码段:简单理解就是操作系统拿出来被共享的代码段,可以被低特权级的用户程序直接访问的代码段,这些代码段,通常是不去访问受保护的资源和某些类型异常处理。
一致代码段访问限制:
1、特权级高的程序不允许访问特权级低的数据:即内核态不允许调用用户态的数据
2、特权级低的程序可以访问到特权级高的程序,但是特权级不会变,即不会从用户态切换到内核态

非一致代码段:为了避免低特权级的访问而被操作系统保护起来的系统代码
非一致性代码访问限制:
1、只允许同特权级访问
2、绝对禁止不同特权级直接访问:内核态不去用户态,用户态也不使用内核态。
3、通常低特权级代码必须通过门调用来实现对高特权级代码段的访问和调用。

一致位:在描述符属性中type(包含4个二进制位)字段的第2位。
当s=1(即描述符类型为数据段或代码段描述符)时type中的4个二进制位情况:
3 2 1 0
执行位:置1时表示可执行,置0时表示不可执行
一致位:置1时表示一致码段,置0时表示非一致码段
读写位:置1时表示可读可写,置0时表示只读
访问位:置1时表示已访问,置0时表示未访问
所以一致代码段和非一致代码段的意思就是指这个一致位是否置1,置1就是一直代码段,置0就为非一致代码段。

一致的意思大约是这样,当转移的目标是一个特权级更高的一致代码段时,当前的特权级会被延续下去,而向特权级更高的非一致性代码段的转移则会引起常规的保护异常,除非使用调用门或者任务门。一致代码段往往是用在内核共享的段,这些段是允许应用程序去访问的,而不需要内核转移到应用程序中来访问这些共享的资源。

之所以这么做是为了系统的安全性考虑,分离内核和用户程序,使内核不能被用户程序干涉,同时避免使用户态程序修改内核态的逻辑,导致在内核态下执行用户程序的代码。上面所说的是代码段,而数据段则全都是非一致的,这意味着不可能被低特权级的代码访问到。然而,与代码段不同的是,数据段可以被更高特权级的代码访问到,而不需要使用特定的门。规则如下:

特权级(低->高)特权级(高->低)相同特权级之间设用于何种代码
一致代码段yesnoyes不访问受保护资源和某些异常处理的系统代码
非一致代码段nonoyes避免低特权级的程序访问而保护起来的代码
数据段(总是非一致)noyesyes

二、特权级

1、cpl、rpl和dpl
cpl是当前进程的权限级别(current privilege level),是当前正在执行的代码所在段的特权级,存在于cs寄存器的低两位。(个人认为可以看成是段描述符未加载如cs前,该段的dpl,加载入cs后就存入cs的低两位,所以叫做cpl,其值就等于原段dpl的值)
rpl说明的是进程对段访问的请求权限(request privilege level),是对于段选择子而言的,每个段选择子都有自己的rpl,它说明的是进程对段访问的请求权限,有点像函数参数。而且rpl对每个段来说不是固定的,两次访问同一段的rpl可以不同。rpl可能会削弱cpl的作用,例如当前cpl=0的进程要访问一个数据段,它把段选择符的rpl设为3,这样它对该段仍然只有特权为3的访问权限。处理器通过检查rpl和cpl来确认一下请求是否合法。即便提出访问请求的段有足够的特权级,如果rpl不够也是不行的。(个人认为是已cpl来访问段dpl所出示的证件(rpl),如果出示证件权级范围在cpl之内且满足dpl的特权检查规则:dpl>=max{cpl,rpl},就能正常通过dpl,反之则不会通过还发生错误)
操作系统过程往往用rpl来避免低特权级应用程序访问高特权级段内的数据。当操作系统过程(被调用过程)从一个应用程序(调用过程)接收到一个选择子是,将会把选择子的rpl设成调用者的特权级。于是,当操作系统用这个去访问相应的段时,处理器将会调用过程的特权级(已经被存到rpl中),而不是更高的操作过程的特权级(cpl)进行特权检验。这样,rpl就保证了操作系统不会越俎代庖地表示一个应用程序去访问一个段,除非这个程序本身是有权限的。()

dpl存储在段描述符中,规定访问该段的权限级别(descriptor privilege level),每个段的dpl固定。当进程访问一个段时,需要进程特权级检查,一般要求dpl>=max{cpl,rpl}。当当前代码段试图访问一个段或者门时,dpl将会和cpl以及段或门选择子的rpl相比较,根据段或者门类型的不同,dpl将会被区别对待,下面介绍一下各种类型的段或者门的情况:
·数据段:dpl规定了可以访问此段的最低特权级。比如,一个数据段的dpl是1,那么只有运行在cpl为0或者1的程序才有权访问它。
·非一致代码段(不使用调用门的情况下):dpl规定访问此段的特权级。比如,一个非一致代码的特权级为0,那么只有cpl为0的程序才可以访问它。
·调用门:dpl规定了当前执行的程序或任务可以访问此调用门的最低特权级(这与数据段的规定是一致的)。
·一致代码段:dpl规定了访问此段的最高特权级。比如,一个一致代码段的dpl是2,那么cpl为0和1的程序将无法访问此段。
·tss:dpl规定了可以访问此tss的最低特权级(这与数据段的规定是一致的)

打个比方,中国官员分为6级:国家主席1、总理2、省长3、市长4、县长5、乡长6,假设当前进程,级别是总理(cpl=2),去聊城(dpl=4)考察,此进程用省长的级别(rpl=3)这样就可以得到足够的优待,但是如果用县长的身份(rpl=5),人家就不鸟你了。为什么采用rpl,是考虑到安全的问题,就好像你命名对一个文件拥有读写权限,为什么用只读打开它呢?--安全。

2、代码间跳转(段间)
普通跳转(没有使用调用门):即jmp或call后跟着48位全指针(16位段选择子+32位地址偏移),且其中的段选择子指向代码段描述符,这样的跳转称为直接(普通)跳转。普通跳转不能使特权级发生跃迁,即不会引起cpl的变化,看下面的详细描述:

代码段要求特权变化
一致代码段cpl >= dpl,rpl不检查,也就是说一致代码段描述符中的dpl规定可以转移到一致代码段的最内层特权级(3级可以转移到0级,而0级只能转移到0级)跳转后程序的cpl=跳转前程序的cpl
非一致代码段一致代码段描述符内dpl的这种解释,正好与正常的dpl的解释相反。这是为了提供对应用程序的共享支持,而不要求改变特权级。跳转后程序的cpl=跳转前程序的cpl

通过跳转门的跳转:当段间转移指令jmp和段间转移指令call后跟着目标段选择子指向一个调用门描述符时,该跳转就是利用调用门的跳转。这是如果选择子后跟着32位的地址偏移,也不会被cpu使用,因为调用门描述符已经记录了目标代码的偏移。使用调用门进行的跳转比普通跳转多一个步骤,即在访问调用门描述符时要将描述符当作一个数据段来检查访问权限,要求指示调用门的选择子的rpl<=门描述符dpl,同时当前代码段cpl<=门描述符dpl,就如同访问数据段一样,要求访问数据段的程序的cpl<=带访问的数据段的dpl,同时选择子的rpl<=待访问的数据段或堆栈段的dpl。只有满足了以上条件,cpu才会进一步从调用门描述符中读取目标代码段的选择子和地址偏移,进行下一步的操作。
从调用门中读取到目标代码的段选择子和地址偏移后,我们当前掌握的信息又回到了先前,和普通跳转站在了同一条起跑线上(普通跳转一开始就得到了目标代码的段选择子和地址偏移),有所不同的是,此时,cpu会将独到的目标代码段选择子中的rpl清零,即忽略了调用门中代码段选择子的rpl的作用。完成这一步后,cpu开始对当前程序的cpl,目标代码段选择子的rpl(事实上它被清零后总能满足要求)以及由目标代码子指示的目标代码段描述符中的dpl进行特权检查,并更具情况进行跳转,具体情况如下:

代码段要求特权变化
一致代码段cpl>=dpl,rpl不检查因为rpl被清零,所以事实上永远满足rpl<=dpl,这一点与普通跳转一致,适用于jmp和call。跳转后程序的cpl=跳转前程序的cpl,因此特权级没有发生跃迁。
非一致代码段(jmp)cpl=dpl(rpl被清零,不检查),若不满足要求则程序引起异常跳转后程序的cpl=dpl,因为前提时cpl=dpl,所以跳转后程序的cpl=dpl不会改变cpl的值,特权级也没有发生变化。如果访问时不满足前提cpl=dpl,则引发异常。
非一致代码段(call)cpl>=dpl(rpl被清零,不检查),若不满足要求则程序引起异常跳转后程序的cpl=dpl,当条件cpl=dpl时,程序跳转后cpl=dpl,特权级不发生跃迁;当cpl>dpl时,程序跳转后cpl=dpl,特权级发生跃迁,这是我们当目前位置唯一见到的使程序当前执行优先级(cpl)发生变化的跳转方法,即用call指令+调用门方式跳转,且目标代码段是非一致代码段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值