CPU段访问控制:特权级(RPL CPL DPL)和代码段一致性
最近笔者回顾CPU硬件的段访问控制机制,重新看到了代码段一致性问题。虽然目前操作系统没有应用分段机制,但了解其运行原理仍然具有吸引力XD。本片文章,我们就来理清CPU段访问控制中,代码段一致性的概念。
Privilege Level 特权级
首先,应当分清三个特权级的基本概念:
DPL (Descriptor Privilege Level 段描述符特权级): 定义于**段描述符 (Segment Descriptor)**中,对于不同的段,DPL的意义不尽相同
- Data Segments 数据段:访问该段的最低特权等级。如果程序特权级过低,则不可访问该段
- Stack Segment 栈段:访问该段的特权等级(需要相同,否则触发
general-protection fault
#GP) - Non-conforming Code Segments 非一致性代码段:Direct Call(直接跳转,不经过 call gate)时,caller需要的特权等级(必须相同)
- Call gate & TSS:访问该Call gate / TSS 的最低特权等级,低权限程序无权使用高权限服务。
- invoking Code Segments via Call Gates 通过调用门调用的代码段:访问该段的最高等级,这里与一般设置不同。事实上,通过调用门调用代码,通常是低特权级程序请求高特权服务时使用,这个设计也符合以上应用需求。详见下一节。
RPL (Requested Privilege Level 请求特权级):定义于段选择子中(最后两位),表示当前段发起请求的特权级(以何种身份发起请求)。可以用于防止低权限程序借用高权限代码破坏高权限段。
CPL (Current Privilege Level 当前特权级): 定义于当前程序的CS中,即
CPL = CS.RPL
。表示当前运行程序的特权级。
特权级检查
特权级检查,在将Segment Selector放入Segment Register时进行。按照上述规则执行检查。
如果检查不通过,通常会产生异常:General-protection fault (#GP)
关于跳转中各种情况的分类解析,详见下节:控制权转移
控制权转移
有多种途径进行控制权的转移:
- 应用程序执行的指令:
JMP
CALL
RET
INT n
IRET
- 来自硬件的事件:中断 interrupt、异常 exception
在跨段的跳转中,会执行特权级检查,跳转主要有以下几种情形:
direct jump
当通过CALL
或者 JMP
直接跳转到另一个代码段时,会检查CPL、目标段描述符的DPL、目标段选择子(Segment Selector)的RPL。此时按照Target Segment Descriptor的C
标志位(Conforming 一致性),可分为两种情况:
一致性代码段(Conforming Code Segment):CPL 必须大于等于DPL(低权限代码借用高权限代码段)。即使跳转到DPL较高(数字小)的一致性代码段时,CPL也不会改变,因此不会进行堆栈切换(Stack-Switch)
可以将一些不需要系统保护的部分API(数学函数、Exception Handlers等)设置在Conforming Segment中,由于CPL不改变,避免其影响高特权级数据
非一致性代码段(non-Conforming Code Segment):CPL一定与Target DPL相同,且RPL小于等于CPL (特权级更高,请求方必须以高权限访问该段)(如果RPL比CPL更低(大于),则表示请求来自低特权级程序,访问失败)
CPL=DPLRPL≤CPLCPL=DPL\\ RPL\le CPL CPL=DPLRPL≤CPL
一般情况下,大部分其他Code Segment都应当设定为非一致性的
Call Gate
**Gate(门)**是一种系统段,它的Segment Descriptor 称为 gate descriptor。通常有四种门:Call Gates 调用门、Trap Gates 陷门、Interrupt Gates 中断门、Task Gates 任务门。这里只讨论Call Gates。
typedef struct _CALL_GATE
{USHORT OffsetLow;USHORT Selector;UCHAR NumberOfArguments:5;UCHAR Reserved:3;UCHAR Type:5; // 01100 in i386, 00100 in i286UCHAR Dpl:2;UCHAR Present:1;USHORT OffsetHigh;
}CALL_GATE,*PCALL_GATE;
当JMP
和CALL
指令的目标段寄存器存放的选择子是Call Gate时,视为使用调用门(忽略偏移,在Gate Descriptor中已经指定)。
经由Call gate调用API时,CPL和RPL都要小于等于(特权级高于)Call gate的DPL
Call
使用调用门时,CPL和RPL都要大于等于Call gate对应Segment的DPL(非Call Gate的DPL)。如果调用者权限更高,则不能通过调用门进行调用;JMP
使用时,若target segment是non-conforming segment,则target DPL必须与CPL相同。
按照目标代码段区分:
一致性代码段:
CPL≥targetDPLCPL \ge target\ DPL CPL≥target DPL
CPL不改变,没有特权级转换。非一致代码段:
JMP
跳转
CPL=targetDPLRPL≤CPLCPL = target\ DPL \\ RPL \le CPL CPL=target DPLRPL≤CPL
事实上,由于RPL被清零,条件二一定被满足。跳转后,CPL不变,没有特权级变化
CALL
跳转
CPL≥targetDPLRPL≤CPLCPL \ge target DPL \\ RPL \le CPL CPL≥targetDPLRPL≤CPL
事实上,由于RPL被清零,条件二一定被满足。由低等级程序通过调用门请求访问高等级代码。
跳转后,CPL=Target DPL,产生特权级变化。(这是目前唯一产生变化的跳转方式)。
由程序中返回
使用RET
指令进行跨段返回时,会检查返回目标的Segment Descriptor中的DPL是否大于等于当前CPL(权限较低),否则说明堆栈中数据错误。
CPU使用栈存储的返回CS中的RPL进行权限判断,检查是否需要改变权限。如果需要改变权限,则同时进行堆栈切换。所以,处理器会先将CS:IP
载入,再载入SS:SP
,同时,CPU还会恢复其他段寄存器的权限,并将指向更高权限的段的选择子置为空。
Real World
从设计原理上,RPL只是提供了一个CPU和操作系统之间的协议:CPU负责检查特权级、操作系统负责RPL的正确性。内核知道用户态请求操作的段选择子,也就能检查/修改对应的RPL,保证其与需要的权限相同。
通常,我们不会使用分段的保护机制,硬件架构建议将所有段的RPL设为0,这样可以通过所有RPL判断,不会进行这部分检查。
CPU段访问控制:特权级(RPL CPL DPL)和代码段一致性相关推荐
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...
在上次的代码基础上,添加一个代码段作为通过调用门转移的目标段.了解一下调用的工作方法,代码分析如下: <<红色标识部分为新增代码>> ; =================== ...
- 特权级——保护模式的特权级检查 DPL,RPL,CPL, 一致代码段,非一致代码段
特权级是保护模式下一个重要的概念,CPL,RPL和DPL是其中的核心概念,查阅资料无数,总结如下. 一.CPL.RPL.DPL简单解释 CPL是当前进程的权限级别(Current Privil ...
- CPL DPL RPL的区别 一致性代码段和非一致性代码段
概述:在谈论保护模式编程的时候,一直会有这样的困惑:为什么除了CPL和DPL还有RPL?什么时候高特权级不能访问低特权级?什么时候低特权级不能访问高特权级?一致性代码和非一致性代码有什么区别?等等这些 ...
- X86(IA32)段权限标志位CPL DPL RPL详解
1.DPL,RPL,CPL 之间的联系和区别是什么?RPL和CPL是必须相同吗?如果相同,为什么要釆用两个而不改用一个呢? 答:特权级是保护模式下一个重要的概念,CPL,RPL和DPL是其中的核心概念 ...
- 代码段间转移控制时的特权级检查(JMP/CALL)——《x86汇编语言:从实模式到保护模式》读书笔记28
代码段间转移控制时的特权级检查(JMP或者CALL指令) 在保护模式下,JMP或CALL指令可以用以下四种方法之一来引用另外一个代码段: 1. 目标操作数含有目标代码段的段选择子和偏移 2. 目标操作 ...
- DPL,RPL,CPL 之间的联系和区别
之所以出现这个定义是因为系统要安全:内核要和用户程序分开..内核一定要安全.不能被用户程序干涉. 但是有时候用户程序也需要读取内核的某些数据,怎么办呢? 操作系统就引入了访问特权等级(0-3)的机制. ...
- DPL RPL CPL区别与联系
先说说他们的含义和存储的位置! PL:Privilege Level.特权级 CPL(Current):当前任务的特权级!内核态的时候,CPL = 0,用户态的时候,CPL = 3:linux中只用了 ...
- 特权级概述(哥子就想知道CPU是如何验证特权级的)GATE+TSS
[0]README text description from orange's implemention of a os . [1]特权级概述 当当前代码段试图访问一个段或者门时,目标段的DPL将会 ...
- 【OS学习笔记】二十四 保护模式七:调用门与依从的代码段----特权级保护
学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 上一篇文章学习了保护模式下的任务与任务隔离,以及简单介绍了保护模式下 ...
最新文章
- 你没听说过的Go语言惊人优点
- 细菌基因组基本概念(一)
- MIPI CSI-2规范一——概述及层级
- 中专计算机系专业总结范文,计算机*的中专生自我鉴定范文
- Nodejs+socket.io搭建WebRTC信令服务器
- 原生javaScript中使用Ajax实现异步通信
- for循环中的setTimeout()
- IDEA 代码格式化设置
- cmd命令跳舞代码_Golang语言元编程之代码生成
- MetaPAD: 从大量文本语料库中发现元模式
- 用python实现聚类分析
- Win11玩游戏延迟高的解决办法
- 第二讲:双活灾备方案建设方法论
- IDEA中如何给代码添加Copyright
- docker-compose 部署prometheus+grafana+alertmanager+chronograf+prometheus-webhook-dingtalk+loki
- could not find included file 'pods/target support files/pods-runner/pods-runner.debug.xcconfig 什么问题
- C++如何定义一个长度超过一百万的整型数组
- 【UE4笔记】蓝图升降电梯
- 6天带你玩转mysql课程第一天
- 溢信IP guard文档加密系统控制台看着正常客户端无加密图标问题解决