特权级1

特权级1——RPL、DPL、CPL
 
 

保护模式中最重要的一个思想就是通过分级把代码隔离了起来,不同的代码在不同的级别 ,使大多数情况下都只和同级代码发生关系。 Intel 的80286以上的cpu可以识別4个特权级(或特权层) ,0级到3级。数值越大特权越小。一般用把系统内核放在0级,系统的其他服务程序位于1、2级,3级则是应用软件。一般情况下代码都在自己的级别下做自己 的工作,同一级别之间可以相互访问,而一般是不允许不同级别的代码间随意访问的。但有时候不同级别的程序之间一定要访问,比如系统的接口函数等,必须能够 使得应用程序能够随意调用。于是Intel将代码分为:

1.非一致码:受到隔离的代码,只能在同一级别间相互访问

2.一致码:不受到隔离的就是,允许被同等级或低等级代码调用

至于这部分我们下回再详细说,这里主要搞清楚RPL、DPL、CPL之间的关系。

Intel设置DPL、RPL、CPL以实现分级和权限检查。

DPL:描述符特权(Descriptor Privilege Level)

存 储在描述符中的权限位,用于描述代码的所属的特权等级,也就是代码本身真正的特权级。一个程序可以使用多个段(Data,Code,Stack)也可以只 用一个code段等。正常的情况下,当程序的环境建立好后,段描述符都不需要改变——当然DPL也不需要改变,因此每个段的DPL值是固定。

RPL:请求特权级RPL(Request Privilege Level)

RPL保存在选择子的最低两位。 RPL 说明的是进程对段访问的请求权限,意思是当前进程想要的请求权限。 RPL 的 值 由程序员自己来自由的设置,并不一定RPL>=CPL,但是当RPL<CPL时,实际起作用的就是CPL了,因为访问时的特权检查是判 断:EPL=max(RPL,CPL)<=DPL是否成立,所以RPL可以看成是每次访问时的附加限制,RPL=0时附加限制最小,RPL=3时附 加限制最大。所以你不要想通过来随便设置一个rpl来访问一个比cpl更内层的段。

因为你不可能得到比自己更高的权限,你申请的权限一定要比你实际权限低才能通过CPU的审查,才能对你放行。所以实际上RPL的作用是程序员可以把自己的程序降级运行——有些时候为了更好的安全性,程序可以在适当的时机把自身降低权限(RPL设成更大的值)。

网上许多人都说在问rpl的作用,我也很晕。Intel的手册中对RPL的作用只是这样做的简短解释的:

The RPL can be used to insure that privileged code does not access a segment on behalf of an application program unless the program itself has access privileges for that segment.

后来找到了一些资料对这段话进行了扩充和举例,我才明白一些:

对于特权级高的进程RPL是作用是防止自己不小心访问到一些资料段。比方说,如果进程A的CPL=0,它知道它的委托进程B的DPL=3,也知道数据段C的DPL=2,而这数据段是不能让CPL>2的进程访问的。

那 么如果你是进程A的程序员根本不需要RPL的帮助,也不会试图让进程A访问数据段C的数据, 因为这样做只会浪费时间。当然如果你一定要访问数据段C的数据然后把数据传给委托进程B,这就是你的选择,你真的可以这样做,但后果自负。只是有时候要访 问的数据段我们不知道它的DPL是怎么,也不知道能不能让进程B访问,其中的一个解决方法就是把委托进程B的DPL以RPL的方法告诉数据段C让它决定接 受或不接受。(我想应该是通过程序把B的DPL装入到A的选择子中,然后再由A去访问数据段C)

下面的2个形象的例子在一定程度上帮助我理解了RPL的作用,所以也粘过来。

例子1:

中 国官员分为6级国家主席1、总理2、省长3、市长4、县长5、乡长6,假设我是当前进程,级别总理(CPL=2),我去聊城市(DPL=4)考察(呵 呵),我用省长的级别(RPL=3 这样也能吓死他们:-))去访问,可以吧,如果我用县长的级别,人家就不理咱了(你看看电视上的微服私访,呵呵),明白了吧!

为什么采用RPL,是考虑到安全的问题,就好像你明明对一个文件用有写权限,为什么用只读打开它呢,还不是为了安全!

例子2:

一 个农民(低特权级)请县长(高特权级)打听一种超级种子,如果找到的话帮忙拿一点回来,听闻这种超级种子可让收成倍增。县长说:好!我认识很多当官的,我 可以帮你打听一下哪里有,但是有些地方如果需要表示身分的话我只能说我是农民的代理人。县长利用自己的身份很容易找到了种子在哪里---找的时候没有人问 起他代表谁。县长问种子管理员可不可以给他一点,管理员说种子不能给农民因为种子还在试验阶段,我们可以给县长让他们带回当地的专家来帮忙一起做试验,但 是一定要县长来申请。那你是谁?县长说我是农民的代理人,因为县长保证他会这样回答的(他也不知道那农民是不是专家),管理员当然不给。县长没办法只能告 诉农民拿不到种子。这件事里面县长是以县长的身份帮农民找到种子,但需要表示身分的时候他说只是农民的代理人。这样做县长可以帮人但也不会给别人利 用。(农民可能把种子拿回来卖钱也说不定,没人知道)

在这里RPL就是县长的另一个身份---农民的代理人也就是农民---他会带在身上,人家没有问他的时候他不会告诉别人,所以别人也就以县长的身分来看待他。当查身份的时候他才告诉你---我是农民的代理人。

RPL保存在段选择子里,而段选择子可以是变数(要不然县长怎样带在身上,这样县长也有机会多代表多一些人),当你用call的时候用上这些变数,这些变数就成了段选择子

事实上RPL跟段本身的特权级DPL和当前特权级CPL没有什么关系,因为RPL的值在成功转跳后并不赋给转跳后的CS.RPL.

 

举系统中实际的个例子:

fread(file_id,n_bytes,buffer_ptr) 这是个文件系统功能函数。假定它的功能是:从一个文件读取 n_byes 个字节数据到缓冲区 buffer_ptr 。这个函数通常是在用户程序中调用,即 cpl 是在用户级别 ( cpl=3) ,而这个程序本身是运行在特权级的。现在假设一块系统数据区域,由 0xfff00 开始,里面有些重要数据。在普通情况下,用户级别是不能写入的。但在特权级别下可以。即: fread 可以改写这一块数据。想想看,如果你如此调用这个系统函数 :fread(01,100,0xfff00) 后果会是什么?在用户级别,你改写了系统数据。多好啊……  
应此 rpl 诞生了。 fread 函数在执行数据写入的时候,它就把自己的的 rpl 设置为用户程序的 cpl ,这样,你在想做坏事,就不那么容易了!

 

 

CPL:当前任务特权(Current Privilege Level)

表 示当前正在执行的代码所处的特权级。CPL保存在CS中的最低两位,是针对CS而言的。当选择子成功装入CS寄存器后,相应的选择子中的RPL就变成了 CPL。因为它的位置变了,已经被装入到CS寄存器中了,所表达的意思也发生了变——原来的要求等级已经得到了满足,就是当前自己的等级。

 

选择子可以有许多个,因此RPL也就有许多个。而CPL就不同了,正在执行的代码在某一时刻就只有这个值唯一的代表程序的CPL.

 

另外特别要求CS与SS的特权级必须保持一致。对于装入DS、ES、FS、GS的选择子INTEL没有给它们起什么特殊的名称,我也不知道应该叫它们什么,也许可以仍然称它为RPL。

 

 

 

应用RPL实现数据段的特权级保护的实例

 

计 算机软件一般由操作系统程序和应用程序组成。为了组建高可靠性的软件系统,要求操作系统的数据不允许被应用程序改变,否则,应用程序会影响系统的安全运 行,严重时导致系统崩溃瓦解。一个由操作系统程序与应用程序组成的软件如图1所示。在操作系统程序中有一MOVE过程把一个数据段中的数据块写到另一个数 据段中,MOVE过程是通过参数传入被调用的,即 MOVE(destination,source,count)。其中:source 源数据块的逻辑地址;destination 目标数据块的逻辑地址;count 传送的字节数

 

 
 

 
 
 

数据块的逻辑地址由数据段选择字对应的数据段描述符和数据块偏移量所描述。

 

MOVE过程是操作系统的程序,它可以合法地被操作系统中的其它过程调用,完成操作系统数据段中的数据块移动和操作系统数据段与应用程序数据段中的数据块移动。但是,若MOVE过程被应用程序调用,操作系统数据段的数据有可能失去保护作用。设应用程序的典型调用情形为:

 

①MOVE(数据块A,数据块1,count)

②MOVE(数据块B,数据块A,count)

③MOVE(数据块2,数据块1,count)

④MOVE(数据块1,数据块A,count)

 

情形①:应用程序通过MOVE过程得到操作系统数据块的信息;

情形②:应用程序利用MOVE过程完成应用程序数据块之间的数据移动;

 

①、②这二种情形是合法的要求。

 

情形③:应用程序控制了操作系统的工作,没有按操作系统的工作步骤,强行改变了数据块2的内容;

情形④:应用程序将应用程序数据块A的内容移动到操作系统数据块1中,自行改变了数据块1的内容;

 

在③、④这二种情形使操作系统的数据得不到核心保护,操作系统的数据受到了应用程序的侵犯。

 

 

针对上述的侵权示例,如何防止应用程序改变操作系统的数据,即情形①和②;并且,应用程序能通过调用操作系统程序中的MOVE过程合法地使用,即情形③和④;这是操作系统软件设计中必须考虑的问题。

 

设调用MOVE过程的程序段Proc为:

 

……

 

LDS EAX,source ;DS:EAX=source源数据块的逻辑地址

 

PUSH DS ;压入source源数据块的选择字

 

PUSH EAX ;压入source源数据块的偏移量

 

LDS EAX,destination ;DS:EAX=destination目标数据块的逻辑地址

 

PUSH DS ;压入destination目标数据块的选择字

 

PUSH EAX ;压入destination目标数据块的偏移量

 

MOV ECX,count ;ECX=传送的字节数count

 

PUSH ECX ;压入传送的字节数count

 

CALL MOVE ;调用MOVE过程,MOVE由调用门描述

 

……

 

如果Proc在操作系统程序中,无论source源数据块和destination目标数据块属于操作系统或应用程序,都能合法的运作。

 

如果Proc在应用程序中,有可能产生情形③和④。例如,应用程序传入的目标数据块选择字的RPL=0,就意味着应用程序要对操作系统的数据段进行非法写入。为此,必须在MOVE过程中加以判断,避免情形③和④的产生。

 

在 MOVE过程中采用的处理方法是:目标数据块选择子的RPL应以主调程序的CPL为准。即采用ARPL指令改目标数据块选择子的RPL为主调程序的 CPL(关于ARPL指令的使用说明见最后)。依据应用程序调用MOVE过程的堆栈,如图2所示,在MOVE过程始部(开始)加入的指令为:

 

MOV AX,SS:[ESP+4] ;AX=CS主调程序的代码段选择字

 

;其RPL字段为主调程序的CPL

 

ARPL SS:[ESP+10],AX ;改目标数据块选择子的RPL为主调程序的CPL

 

MOV ES,SS:[ESP+10] ;ES=目标数据块选择子(其RPL字段为主调程序 ;的CPL)

 

……

 

进 行了上述处理以后,如果应用程序传入的目标数据块选择字的RPL=0,ARPL把它修改为RPL=3,再传送到ES段寄存器中,显然不能满足选择字的装载 要求,即MAX(CPL,RPL)≤DPL,其中,MOVE过程的CPL=0;目标数据块选择字对应的数据段描述符中的DPL=0。CPU内部立即产生通 用保护异常中断进行处理。处理的结果通常为:终止当前的MOVE过程操作,返回应用程序;或终止应用程序的运行,返回操作系统。从而达到了保护目的。而情 形①、②,应用程序完全可以合法实现。

 

 

 

[关于ARPL指令的使用说明]

 

调整申请特权级指令: ARPL OPRD1,OPRD2

其 中,操作数OPRD1可以是16位通用寄存器或存储单元,操作数OPRD2是16位通用寄存器。该指令把操作数OPRD1和OPRD2视为两个选择子,用 OPRD2的RPL去检查OPRD1的RPL。(选择子OPRD1和OPRD2的RPL分别由它们的最低2个位规定。)

如 果OPRD1的RPL值小于OPRD2的RPL值(OPRD1的特权级高于OPRD2),那么零标志ZF被置1,并把OPRD2的RPL值赋予OPRD1 的RPL(使两个操作数的最低2位相等);否则,零标志ZF被清0。OPRD1和OPRD2都可为空选择子。该指令只影响ZF标志。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值