概述:在谈论保护模式编程的时候,一直会有这样的困惑:为什么除了CPL和DPL还有RPL?什么时候高特权级不能访问低特权级?什么时候低特权级不能访问高特权级?一致性代码和非一致性代码有什么区别?等等这些问题,如果仅仅停留在知其然的级别,很容易会困惑,本文主要说明以上问题的答案和蕴涵在背后的原因。

1.特权级


       首先,了解以下操作系统的特权级

1CPL是存寄存器如CS中,当前特权级。只有0和3两个值,分别表示用户态和内核态。

2)RPL是代码中根据不同段跳转而确定,以动态刷新CS里的CPL,在代码段选择符中。而且RPL对每个段来说不是固定的,两次访问同一段时的RPL可以不同。

3)DPL是在GDT/LDT描述符表中,静态的。

RPL是用来做什么的?

Intel手册上的解释为:TheRPL
can be used to insure that privileged code does not access asegment on behalf of an application program unless the program itselfhas access privileges for that segment.(RPL能够用来确保具有特权级的代码不会代表另一个应用程序去访问一个段,除非那个应用程序具有访问那个段的权限.)

比方说:A进程的DPL为0,C进程的DPL为1,现在有一个B进程他的DPL为2,这B进程想委托A进程去访问C的数据,如果没有RPL的话这样的委托访问是可以成功的,但这样是非常不安全的(实际上B没有访问C的权限,但是A有这个权限)。有了RPL以后A进程在访问C的时候还要受到RPL的约束,此时可以将访问C的选择子的RPL设为B的DPL,这样A的访问权限就相当为EPL=max(RPL,DPL)=2,这样他就无法代表B去越权访问C了。RPL相当于附加的一个权限控制,只有当RPL>DPL的时候,才起到实际的限制作用。

简单的说就是这样:B需要委托A去到C那里办理某件事情,但是A的权利太大,所以需要附加委托人的权利。用一个不恰当的比喻,你爷爷是皇帝,你爸爸是太子,你是太子的儿子,你爷爷还有很多孙子;其中太子的请求,如果不考虑其他因素,皇帝都会答应;你要去对皇帝递交某个请求,来请你爸爸传递,你爷爷看见是你爸爸,还要核对你爸爸是帮谁传递的请求,如果是帮你,你皇帝爷爷就批准了,如果你爸爸是递交的外人的请求,你爷爷未必会批准。

2.段间的转移和跳转

程序是通过选择子/门调用等等来在段之间来回走动的.实现用户级与系统级的调用跳转.

2.1数据段与堆栈段

    所有的数据段都是非一致性的,就是说他们不能被低特权级的程序访问,但是可以被高特权级的程序访问而不需使用特殊的访问门。这里,RPL可能会削弱CPL的作用,访问数据段或堆栈段时,默认用CPL和RPL中的最小特权级去访问数据段,所以max {CPL, RPL} ≤ DPL,否则访问失败。

2.2代码段

转跳后程序的CPL(CS.RPL)只会有下面的俩种可能

1)转跳后程序的CPL(CS.RPL)=转跳前程序的CPL(CS.RPL)
2)或转跳后程序的CPL(CS.RPL)= 转跳后程序的CodeDescriptor.DPL

准则:RPL是不会赋值给CPL的

如何决定跳转之后CPL的值呢?

1)如果能成功转跳到一致代码段,转跳后程序的CPL(CS.RPL)=转跳前程序的CPL(CS.RPL),(转跳后程序的CPL继承了转跳前程序的CPL,一致一致,翻译时一致含义就是这个意思!)
2)如果能成功转跳到非一致代码段,转跳后程序的CPL(CS.RPL) =转跳后程序的Descriptor.DPL。(转跳后程序的CPL变成了该代码段的特权级.我在前面提到DPL是段描述符中的特权级,它的本意是用来代表它所描述的段的特权级)

2.3.一致性代码与非一致性代码段

什么是一致代码和非一致代码段?为什么要作这个区别?

代码段可以是一致性的或者非一致性的。向特权级更高的一致性代码段的控制转移,允许程序以当前特权级继续执行,向不同特权级的非一致代码段转移将导致一般保护异常,除非使用了任务门或者调用门。产生一致性代码和非一致性代码的主要原因是:单纯的0-3特权级只能保证高特权级可以访问特权级的东西,而低特权级的段有时候要访问内核数据段,此时就需要一些灵活策略。

不访问保护措施的系统工具和某些异常类型的处理过程需要放在一致性代码段中。需要防止低特权级程序访问的工具要放在非一致代码段中。

1)一致代码段:

简单理解,就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接调用访问的代码.

通常这些共享代码,是"不访问"受保护的资源和某些类型异常处理。比如一些数学计算函数库,为纯粹的数学运算计算,

一致代码段的限制作用

1.1).特权级高的程序不允许访问特权级低的数据:核心态不允许调用用户态的数据.
1.2).特权级低的程序可以访问到特权级高的数据.但是特权级不会改变:用户态还是用户态.

2)非一致代码段:

为了避免低特权级的访问而被操作系统保护起来的系统代码.

非一致代码段的限制作用

2.1).只允许同级间访问.
2.2).绝对禁止不同级访问:核心态不用用户态.用户态也不使用核心态.

通常低特权代码必须通过"门"来实现对高特权代码的访问和调用.

2.4段间成功跳转的条件

    明晰一些概念:段的保护观念是高特权级不找低特权级办事,低特权级找高特权级帮忙;但是低特权级不能直接处理一些事情,而高特权级可以访问低特权级。(好吧,这句话好像矛盾了)

    具体而言:还是要问怎样才能成功转跳?这里分两种情况:

2.4.1普通转跳(没有经过Gate 这东西):

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

1)目标是一致代码段:
要求:CPL(CS.RPL)>=DestinationDescriptorCode.DPL ,其他RPL是不检查的。
原因:一致性代码设计的初衷就是让低特权级可以访问到高特权级的东西

结果:CPL不变

异常原因:CPL<DPL

总结:一致性代码,不允许高特权级访问低特权级的内容。

2)目标是非一致代码段:
要求:CPL(CS.RPL)=DestinationDescriptorCode.DPL ANDRPL≤CPL(CS.RPL)
原因:非一致性代码的设计初衷就是让低特权级无法接触到高特权级的代码。

结果:CPL不变
异常原因:如果访问时不满足前提CPL=DPL,则引发异常。

总结:非一致性代码,只允许同特权级的进程之间互相访问。

2.4.2通过调用门的跳转:

当段间转移指令JMP和段间转移指令CALL后跟着的目标段选择子指向一个调用门描述符时,该跳转就是利用调用门的跳转。这时如果选择子后跟着32位的地址偏移,也不会被cpu使用,因为调用门描述符已经记录了目标代码的偏移。使用调门进行的跳转比普通跳转多一个步骤,即在访问调用门描述符时要将描述符当作一个数据段来检查访问权限,要求指示调用门的选择子的RPL≤门描述符DPL,同时当前代码段CPL≤门描述符DPL,就如同访问数据段一样,要求访问数据段的程序的CPL≤待访问的数据段的DPL,同时选择子的RPL≤待访问的数据段或堆栈段的DPL。只有满足了以上条件,CPU才会进一步从调用门描述符中读取目标代码段的选择子和地址偏移,进行下一步的操作。

从调用门中读取到目标代码的段选择子和地址偏移后,我们当前掌握的信息又回到了先前,和普通跳转站在了同一条起跑线上(普通跳转一开始就得到了目标代码的段选择子和地址偏移),有所不同的是,此时,CPU会将读到的目标代码段选择子中的RPL清0,即忽略了调用门中代码段选择子的RPL的作用。完成这一步后,CPU开始对当前程序的CPL,目标代码段选择子的RPL(事实上它被清0后总能满足要求)以及由目标代码选择子指示的目标代码段描述符中的DPL进行特权级检查,并根据情况进行跳转,具体情况如下:

目标是一致代码段:
要求:CPL(CS.RPL)≥DestinationDescriptorCode.DPL ,RPL不检查,因为RPL被清0,所以事实上永远满足RPL≤DPL,这一点与普通跳转一致,适用于JMP和CALL。
         转跳后程序的CPL(NewCS.RPL) = 转跳前程序的CPL( OldCS.RPL),因此特权级没有发生跃迁。

目标是非一致代码段:

当用JMP指令跳转时:
    要求:CPL(CS.RPL)=DestinationDescriptorCode.DPL AND  RPL<= CPL(CS.RPL)(事实上因为RPL被清0,所以RPL≤CPL总能满足,因此RPL与CPL的关系在此不检查)。若不满足要求则程序引起异常。
         转跳后程序的CPL(NewCS.RPL) = DestinationDescriptorCode.DPL
    因为前提是CPL=DPL,所以转跳后程序的CPL(NewCS.RPL) = DestinationDescriptorCode.DPL不会改变CPL的值,特权级也没有发生变化。如果访问时不满足前提CPL=DPL,则引发异常。

当用CALL指令跳转时:

要求:CPL(CS.RPL)≥DestinationDescriptorCode.DPL(RPL被清0,不检查),若不满足要求则程序引起异常。

转跳后程序的CPL(NewCS.RPL) = DestinationDescriptorCode.DPL

当条件CPL=DPL时,程序跳转后CPL=DPL,特权级不发生跃迁;当CPL>DPL时,程序跳转后CPL=DPL,特权级发生跃迁,这是我们当目前位置唯一见到的使程序当前执行优先级(CPL)发生变化的跳转方法,即用CALL指令+调用门方式跳转,且目标代码段是非一致代码段。

总结:以上介绍了两种情况的跳转,分别是普通跳转和使用调用门的跳转,其中又可细分为JMP跳转和CALL跳转,跳转成功已否是由CPL,RPL和DPL综合决定的。所有跳转都是从低特权级代码向同级或更高特权级(DPL)跳转,但保持当前执行特权级(CPL)不变,这里有点难于区别为什么说向高特权级跳转,又说特权级没变,这里“高特权级”是指目标代码段描述符的DPL,它规定了可以跳转到该段代码的最高特权级;而后面的CPL不变才真正说明了特权级未发生跃迁。我们可以看到,只有用CALL指令

CPL DPL RPL的区别 一致性代码段和非一致性代码段相关推荐

  1. 一致代码段与非一致代码段

    首先,我们先来看几个问题: 一致代码段和非一致代码段是什么? 为什么要有一致代码段和非一致代码段? 系统提供怎样的机制来使用户程序访问内核数据? 程序如何在段与段之间跳转? 接下来,我们将讨论上述这些 ...

  2. 统一代码段与非一致代码段

    一致代码段与非一致代码段 上几篇文章,我们一直在讨论的都是 GDT 相关的一些问题,现在我们知道在系统在从实模式向保护模式跳转时,GDT 是必须要准备的结构.在介绍这一跳转之前,这篇文章我们来介绍两个 ...

  3. 静态代码块和非静态代码块的区别

    摘自原文 小结: 1.静态代码块是在类加载时自动执行的,非静态代码块在创建对象自动执行的代码,不创建对象不执行该类的非静态代码块. 顺序: 静态代码块-->非静态代码块-->类构造方法. ...

  4. java中static代码块与非静态代码块

    static代码块与非静态代码块的区别: static代是码块是在类加载时就加载的,而非静态代码块只有在对象实例化时才执行! 转载于:https://www.cnblogs.com/dazhuzhu/ ...

  5. java中代码块之静态代码块和非静态代码块

    一.代码块: 语法:使用{}包裹的,可以在{}中写代码. 修饰符:static 或者不修饰. static修饰的为静态代码代码块. 格式: //静态代码块,随着类的加载児执行static{System ...

  6. 静态代码块、非静态代码块、构造函数执行顺序

    静态代码块.非静态代码块.构造函数执行顺序 /*** 类的实例化顺序,静态代码块.非静态代码块.构造函数.* @author MING*/ class Person {static String na ...

  7. shaderTextView 闪动文字,static{}(静态代码块)与{}(非静态代码块)的异同点

    目录 shaderTextView  闪动文字 static{}(静态代码块)与{}(非静态代码块)的异同点 shaderTextView  闪动文字 package com.example.zhan ...

  8. java 代码块:静态代码块和非静态代码块

    main方法是程序的入口,加入没有main方法程序无法启动,但是main方法不是第一个执行的. 我认为:在这个类加载时,编译器会找到main方法,从这里开始运行,但是当你把这个类加载的时候,静态代码块 ...

  9. 静态代码块、非静态代码块、构造函数三者执行顺序

    主要探讨一下关于静态代码块,非静态代码块,构造函数的执行顺序. 如有错误,欢迎指出. 首先: 静态成员变量和静态代码块的优先级是一样的,先定义的先执行. 在创建一个对象的时候会执行非静态代码块和构造函 ...

最新文章

  1. 中国云计算市场加速发展 今年有望突破3000亿
  2. 几则常用的BASIS技巧整理
  3. swift. 扩展类添加属性_swift中的声明关键字详解
  4. python discuz搜索api_python如何模拟搜索引擎分词
  5. php怎么创建进程,在php中为长时间运行的进程创建后台进程
  6. groovy+mysql数据库_使用Groovy连接到MySQL
  7. 18-09-06天津 关于Excel的一些操作
  8. win7局域网拷贝其他计算机文件,局域网共享,教您win7局域网文件共享怎么设置
  9. 基于Forest实践|如何更优雅的统一处理请求签名
  10. 前端实习周记07(毕业论文开题了。。。欧耶。。。欧耶。。。耶。。。)
  11. 物联16:4 ISO/IEC 14443-3 防冲突、防碰撞算法、Type A、Type B
  12. 东北大学秦皇岛分校计算机类排名,东北大学秦皇岛分校全国排名,2021东北大学秦皇岛分校排名榜...
  13. oracle tlv,OSPF GR(Graceful Restart,平滑重启)技术
  14. python excel xlwngs 受保护的视图解除方法
  15. html5 js获取鼠标坐标,js怎么获取鼠标在div中的相对位置
  16. 每个程序员都有的经历:从程序员到高级架构师,必须经历的三个阶段
  17. 【centos7中使用docker安装KLEE】
  18. cpa考试科目计算机,高顿教育:CPA考试计算器如何选择
  19. Python 爬取周杰伦歌曲信息,爬取豆瓣top250的电影,并保存至excel中
  20. 第三章:进程线程模型

热门文章

  1. POJ1151基本的扫描线求面积
  2. UVA11389巴士司机问题
  3. 【Linux 内核】编译 Linux 内核 ⑤ ( 查看 .config 编译配置文件 | 正式编译内核 )
  4. 【C 语言】文件操作 ( 读文本文件 | 文本加密解密 | fgets 函数 | fputs 函数 )
  5. Centos 7和Centos 6的防火墙
  6. 最常用的15大Eclipse开发快捷键技巧
  7. chrome手机模拟器显示尺寸不正确
  8. document事件及例子
  9. 上周热点回顾(9.7-9.13)
  10. GridView自定义分页