CPU特权级保护

2023-11-10

1.特权级

1.1特权级

处理器段保护机制可以识别0-3共4级特权级,数值越大,特权越小。处理器通过识别CPL、DPL、RPL这三种特权级来进行特权级校验

(1)CPL:CPL是当前正在执行程序或任务的特权级。它存放在CS和SS段寄存器的0位和1位。通常CPL等于当前代码段的特权级。当程序把控制转移到另一个具有不同特权级的代码段中时,处理器就会改变CPL。

(2)DPL:DPL是一个段或门的特权级别。它存放在段或门的描述符的DPL字段中。在当前执行代码段试图访问一个段或门时,段或门的DPL会用来与CPL以及段或门选择符中的RPL做比较。根据被访问的段或门的类型不同,DPL的意义也不同

(3)RPL:RPL是一种赋予段选择符的超越特权级,存放在在选择符的位0和位1中。处理器会同时检查RPL和CPL,以确定是否允许访问一个段。即使程序或任务有足够的特权级CPL来访问一个段,但是如果提供的RPL特权级不足则访问也将拒绝。即:如果段选择符的RPL的数值大于CPL,那么RPL将覆盖CPL(而是用RPL作为检查比较的特权级)。RPL可以用来确保高特权级的代码不会代表应用程序去访问一个段,除非应用程序自己具有访问这个段的权限--这句话来itel手册,比较抽象,后面会讲解。

2.为什么增加RPL

Intel手册上的解释为: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进程的DPL为0,C进程的DPL为1,现在有一个B进程他的DPL为2,这B进程想委托A进程(外围程序可以访问一致代码段的内核)去访问C的数据(内核可以访问外围数据),
如果没有RPL来限制的话,这样的委托访问是可以成功的,但这样是非常不安全的。
有了RPL以后,A进程在访问C的时候还要受到RPL的约束,此时可以将访问C的选择子的RPL设为B的DPL,这样A的访问权限就相当为EPL=max(RPL,DPL)=2,这样他就无法代表B去越权访问C了。(那还要委托A干嘛?反正B如果不够权限,委托谁都没用;如果B有权限,不用委托别人也可以啊?)
有RPL的情形,CPU同时检查CPL和RPL来判断是否允许对一个段的访问。在低特权级代码调用高特权级代码时,你可以把RPL认为是调用者CPL的影子。即使高特权级代码在运行,但它是应低特权级代码的请求,作为低特权级代码的代理在执行任务,在必要的时候,RPL作为对CPL的覆盖,可以削弱当前执行代码的可访问的区域,从而保证高特权级代码不会代表低特权级代码去访问一个后者没有访问权限的段。
这里有一个问题,就是低特权级代码在向高特权级代码传递段选择子时,可以任意设置RPL。所以x86处理器有一条专门的指令ARPL用来纠正RPL。

3.RPL的理解

CPL和DPL都是见字面就能理解含义的。唯独RPL不容易理解。
今天就说说我的理解,将来回头来看看,今天说的到底对不对。
1、- 当前进程的意愿 -
RPL代表了当前进程的意愿(因为是一种request)。注意,是当前进程的意愿而不是别的进程。其次是一种意愿,是否实现还有待CPU的许可。
2、- 不能超越自己的特权级 -
前面的帖子已经说了,RPL可以由当前进程随便写,但是CPU会检查RPL和CPL的取值,如果RPL填写的特权级比自己实际情况还高,CPU就不会认可,仍旧给他当前的权限。
3、- 只能下降权限 -
鉴于上面的原因,使用RPL的真正情况就是当前进程使用比自己低的或者相同的RPL。这种情况最典型的,就是外围程序A调用内核B,然后通过内核B再访问程序C。由于访问的来源是A,所以内核为了安全起见,将RPL(来自A的访问意愿)设置为A的DPL。这样在逻辑上就完整了。内核就不会越俎代庖了。

参考:

CPL,DPL和RPL总结

用比喻类比说明CPU的特权级DPL - CPL - RPL _dpl=0表示cpu_MOOD的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CPU特权级保护 的相关文章

  • 从命名管道读取

    我必须实现一个 打印服务器 我有 1 个客户端文件和 1 个服务器文件 include
  • 从 Java 读取 /dev/input/js0

    我正在尝试阅读 dev input js0来自Java 但我不断得到 java io IOException Invalid argument at java io FileInputStream read0 Native Method a
  • 编译器 libstdc++ 版本与系统版本

    我试图了解 g 如何选择它链接的 libstdc 版本 以及当库的 系统 版本不同时它意味着什么 我正在使用 gcc g 4 1 2 根据ABI 指南 http gcc gnu org onlinedocs libstdc manual a
  • 页面错误陷阱的成本

    我有一个应用程序 它定期 每 1 或 2 秒后 通过分叉自身来获取检查点 因此 检查点是原始进程的一个分支 它一直保持空闲状态 直到原始进程发生某些错误时被要求启动 现在我的问题是fork的写时复制机制的成本有多大 每当原始进程写入内存页面
  • 让“git pull”在拉取不同分支时要求确认

    当同时处理许多项目和分支时 我偶尔会犯一些愚蠢的错误 比如拉入错误的分支 例如在分支上master I did git pull origin dangerous code并且有一段时间没有注意到这一点 这个小错误造成了很大的混乱 当我尝试
  • 如何随时暂停 pthread?

    最近我开始将 ucos ii 移植到 Ubuntu PC 上 我们知道 在pthread的回调函数中的 while 循环中简单地添加一个标志来执行暂停和恢复是不可能模拟ucos ii中的 进程 的 如下解决方案 因为ucos ii中的 进程
  • Linux shell 命令逐块读取/打印文件

    是否有一个标准的 Linux 命令可以用来逐块读取文件 例如 我有一个大小为 6kB 的文件 我想读取 打印第一个 1kB 然后是第二个 1kB 看来猫 头 尾在这种情况下不起作用 非常感谢 你可以这样做read n在循环中 while r
  • 如何使用sprof?

    请举例说明 从邮件中找到here http sources redhat com ml libc alpha 2003 07 msg00029 html and here http sourceware org ml binutils 20
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 在64位操作系统上以32位模式和64位模式编译ioctl函数的执行有什么不同?

    我有 64 位 Enterprise SuSE 11 我有一个应用程序 它打开 HIDRAW 设备并在其上操作 ioctl 函数以从该设备获取原始信息 如下所示 struct hidraw devinfo devinfo int fd op
  • 有关 Linux 内存类型的问题

    关于Linux内存我有以下问题 我知道活动内存是最常访问的内存部分 但是有人可以解释一下 linux 如何考虑将内存位置用于活动内存或非活动内存 主动存储器由哪些部分组成 磁盘 文件缓存是否被视为活动内存的一部分 有什么区别Buffers
  • 跟踪 pthread 调度

    我想做的是创建某种图表 详细说明 Linux 中 两个 线程的执行情况 我不需要查看线程的作用 只需查看它们何时被安排以及持续多长时间 基本上是一条时间线 在过去的几个小时里 我一直在互联网上搜索跟踪 pthread 调度的方法 不幸的是
  • 如何使用libaudit?

    我试图了解如何使用 libaudit 我想接收有关使用 C C 的用户操作的事件 我不明白如何设置规则 以及如何获取有关用户操作的信息 例如 我想获取用户创建目录时的信息 int audit fd audit open struct aud
  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • ARM 系统调用的接口是什么?它在 Linux 内核中的何处定义?

    我读过有关 Linux 中的系统调用的内容 并且到处都给出了有关 x86 架构的描述 0x80中断和SYSENTER 但我无法追踪 ARM 架构中系统调用的文件和进程 任何人都可以帮忙吗 我知道的几个相关文件是 arch arm kerne
  • 在 Ubuntu 上纯粹通过 bash 脚本安装 mysql 5.7

    我想要一个无需任何手动输入即可安装 MySQL 5 7 实例的 bash 脚本 我正在关注数字海洋教程 https www digitalocean com community tutorials how to install mysql
  • 将 stdout 作为命令行 util 的文件名传递?

    我正在使用一个命令行实用程序 该实用程序需要传递文件名以将输出写入 例如 foo o output txt 它唯一写入的东西stdout是一条消息 表明它运行成功 我希望能够通过管道传输写入的所有内容output txt到另一个命令行实用程
  • 如何从“git log”中查看 Git 中的特定版本?

    My git log显示为 enter code here git trial git log commit 4c5bc66ae50780cf8dcaf032da98422aea6e2cf7 Author king lt email pro
  • gdb 错误 - 文件不是可执行格式:无法识别文件格式

    我正在尝试使用 gdb 调试某个名为 xdf 的程序 但是当我运行 gdb xdf 时 出现以下错误 home nealtitusthomas X ray astronomy heasoft 6 24 x86 64 pc linux gnu
  • 如何仅将整个嵌套目录中的头文件复制到另一个目录,在复制到新文件夹后保持相同的层次结构

    我有一个目录 其中有很多头文件 h 和其他 o 和 c 文件以及其他文件 这个目录里面有很多嵌套的目录 我只想将头文件复制到一个单独的目录 并在新目录中保留相同的结构 cp rf oldDirectory newDirectory将复制所有

随机推荐