当前位置: 首页 > news >正文

长模式下的段权限检查机制

在x86_64的长模式(Long Mode)下,段机制发生了根本性的简化,段基址和段限长检查被弱化,但权限检查(即特权级检查)仍然至关重要。长模式下的段权限检查,实际上只围绕一个核心规则:数据段的访问权限检查被大幅简化,但代码段和控制转移的权限检查依然严格。


一、长模式下的关键变化(与保护模式对比)

特性保护模式(32位)长模式(64位)
段基址可任意指定CS/SS/DS/ES 基址强制为0(FS/GS可通过MSR独立设置)
段限长有效(基于Limit字段)CS/SS/DS/ES 段限长被忽略(视为全64位地址空间)
分段检查每个内存访问都检查基址+限长仅对FS/GS进行基址/限长检查,其他段跳过
权限检查(DPL/RPL)严格检查仍然严格检查(特别是代码段和控制转移)
段类型检查完整检查(代码/数据/系统段)简化为代码段(CS)数据段(DS/SS/ES)两类
CALL/JMP门支持任务门、调用门等不再支持任务门/调用门(使用中断门/陷阱门替代)

二、长模式下的段权限检查核心机制

1. 当前特权级(CPL)的确定

CPU通过CS段选择子RPL(请求特权级)字段来确定当前特权级(CPL),而不是通过段描述符中的DPL。具体地,在长模式下:

  • CS.RPL = 0:内核态(ring 0)

  • CS.RPL = 3:用户态(ring 3)

注意:长模式只支持ring 0ring 3,ring 1和ring 2在长模式下没有实际用途(但段描述符中的DPL仍然允许设置为1或2,只是操作系统通常不使用)。

2. 数据段访问权限检查(DS/SS/ES)

长模式下,数据段的权限检查简化为仅检查CPL与段描述符DPL的关系

条件结果
CPL <= DPL(数值上:0 ≤ 3?不对,数值越小特权越高)允许访问
CPL > DPL触发#GP(通用保护异常)

具体规则

  • CPL=0(内核)可访问任何DPL的数据段(DPL=0/1/2/3)

  • CPL=3(用户)只能访问DPL=3的数据段(不能访问DPL=0/1/2)

示例

; 用户态代码(CS.RPL = 3) mov rax, [0x12345678] ; 数据段默认为DS(用户态DS指向DPL=3的段)→ 允许 mov rax, [fs:0x10] ; FS基址独立,权限检查基于GS的段描述符(通常也是DPL=3)→ 允许

如果用户态试图加载一个DPL=0的内核数据段到DS,会触发#GP

3. 代码段访问与控制转移检查

这是长模式下权限检查最复杂的部分,涉及代码段切换控制转移指令JMPCALLRETIRET等)。

a. 直接转移(JMP/CALL到同一代码段)
  • 在同一代码段内跳转:不涉及CPL变化,只检查目标地址是否在当前段限长内(但段限长被忽略,所以总是允许)。

  • 到不同代码段的跳转(通过JMP/CALL远跳转):在长模式下,直接远跳转(使用JMP FAR)被禁止,只能通过中断门/陷阱门系统调用SYSCALL/SYSRET)实现跨段转移。

b. 通过中断门/陷阱门的控制转移(异常和中断)

这是长模式中最常见的跨段转移方式。CPU通过IDT(中断描述符表)中的门描述符来转移控制:

权限检查条件

  1. 当前特权级(CPL)必须等于中断门的DPL(或者数值上小于DPL,即特权级更高?不,对于中断门,要求CPL >= DPL?这里需要澄清):

    • 用户态(CPL=3)可以通过int 0x80触发一个DPL=3的中断门(例如Linux的系统调用)。

    • 内核态(CPL=0)触发任何中断(通常内核中断门的DPL=0)。

  2. CPL <= 目标代码段的DPL?不,对于中断门,目标代码段的DPL通常是0(内核代码段),但中断门本身有DPL,权限检查的是:CPL必须 <= 中断门的DPL(数值上,0 <= 3,内核可触发任何中断;3 <= 3,用户可触发DPL=3的中断)。

  3. 目标段描述符的DPL(代码段的DPL)决定了目标代码段运行的特权级(通常是0)。

示例(Linux系统调用int 0x80):

  • 用户态(CPL=3)执行int 0x80

  • IDT中的0x80中断门的DPL=3(允许用户态触发)。

  • 目标代码段(__KERNEL_CS)的DPL=0(内核态)。

  • 权限检查:CPL(3) <= 中断门DPL(3)→ 允许,转移到内核代码段(CPL变为0)。

c. 系统调用(SYSCALL/SYSRET

长模式下的系统调用不经过中断门,直接使用SYSCALL指令,它绕过了一般的段权限检查,但依然通过MSR(IA32_STARIA32_LSTAR)指定目标代码段和栈,并在执行时自动切换CPL(从3到0),返回时通过SYSRET切换回用户态(从0到3)。

d. 返回指令(RET/IRET
  • IRET(从中断返回):会检查返回目标代码段的CPL是否与栈上的CS选择子的RPL一致,如果不一致(例如内核返回到用户态),会触发#GP

  • RET(远返回):在长模式下,RETF(远返回)是不允许的(会被忽略或触发#GP)。


三、长模式下的段权限检查流程(状态机)

┌─────────────────┐ │ 当前 CPL │ = CS.RPL (从段选择子读取) │ (0 或 3) │ └────────┬────────┘ │ ▼ ┌───────────────────┐ │ 数据访问(DS/SS/ES) │ │ 检查:CPL <= 目标段描述符的 DPL │ └────────┬──────────┘ │ ▼ ┌───────────────────┐ │ 代码转移(JMP/CALL/IRET) │ │ 1. 检查中断门/陷阱门的 DPL │ │ 2. 检查目标代码段的 DPL │ │ 3. 检查栈段(SS)的 DPL │ └────────┬──────────┘ │ ▼ ┌────────────────────┐ │ 返回(IRET) │ │ 检查返回目标 CS 的 RPL 与当前 CPL │ └────────────────────┘

四、段寄存器在长模式下的实际角色

段寄存器基址段限长权限检查角色
CS0(固定)忽略确定CPL(通过RPL字段);代码执行权限
SS0(固定)忽略特权级切换时确定是否切换栈(通过IRET
DS0(固定)忽略数据访问权限检查(CPL <= DPL
ES0(固定)忽略同DS
FS / GS独立MSR设置可设置仍进行完整的基址/限长检查(用于线程局部存储、CPU核心数据)

五、实际代码示例

// 尝试在内核态加载用户态数据段(x86_64) static inline void load_user_ds(void) { asm volatile ( "mov %0, %%ds\n" : : "r" (__USER_DS) // 用户态数据段选择子(DPL=3) : "memory" ); } // 如果在内核(CPL=0)中执行此函数,会触发 #GP // 因为 CPL(0) > 用户态DS的DPL(3)?不,CPL=0 <= DPL=3,应该允许! // 实际上,内核可以加载用户态DS(因为0 <= 3),但访问内存时,DS的基址为0,且权限检查基于CPL与DS.DPL的关系。 // 但出于安全考虑,Linux内核通常不这样做。

六、总结:长模式下的段权限检查规则

操作检查内容失败结果
加载数据段(DS/SS/ES)CPL <= 段描述符.DPL段类型 == 数据段#GP
加载代码段(CS)仅通过中断门/陷阱门或SYSCALL间接加载,不能直接LOAD#GP
中断/异常处理CPL <= 中断门.DPL目标代码段.DPL == 0(通常)#GP/#DF
IRET返回栈上CS.RPL == 目标CPLCPL <= 目标栈段.DPL#GP
SYSCALL进入无检查(硬件直接切换)#GP(如果MSR配置错误)
SYSRET返回要求目标CS.RPL == 3 且 目标栈段.DPL == 3#GP

七、常见误解澄清

  1. “长模式下段寄存器被弃用了”→ 不准确。CSSS仍然用于特权级管理,FSGS仍然用于TLS/CPU核心数据。

  2. “长模式下段限长检查被完全忽略”→ 仅对CSDSSSES而言。FSGS仍然有基址和限长(通过MSR设置)。

  3. “长模式下CPL只能从CS选择子读取”→ 正确。段描述符的DPL只用于数据段权限检查,不用于确定CPL。

http://www.jsqmd.com/news/1332127/

相关文章:

  • 四川金属废料回收口碑怎么样?2026年行业观察与服务机构参考 - 优质品牌商家
  • 好友一键导出备份,简单又快速!
  • 第9讲:多 Agent 协作——让多个智能体分工合作
  • 前端Canvas动画转GIF实战:基于gif.js的完整方案与优化指南
  • Flutter+OpenHarmony游戏导航系统开发实战
  • 破解南阳高盐碱环境防碱防潮难题:SBR结构本体防护方法论如何实现长期耐候? - 汇聚至此
  • Windows批处理文件双击失效:从文件关联到系统权限的全面排查指南
  • 如何用背钻实现低成本高可靠量产?
  • 标注员标注合肥话时分不清声调的差异,标注结果全是错的
  • 企业AI Agent治理平台:从成本失控到规模化智能的架构与实践
  • HLS协议深度解析:从HTTP流媒体原理到直播系统实战搭建
  • 架构设计之Redisson分布式锁-可重入异步锁(二)
  • 黔东南家里到处漏水发霉?卫生间、屋顶外墙全场景漏水原因一次讲透 - 宅安选房屋修缮
  • 通知!2026年度恩施州中、初级职称申报时间+申报材料清单
  • Excel GetPivotData函数详解:透视表动态引用与数据查询实战
  • 恒美智造熔融指数测定仪应用白皮书:精准检测赋能全产业链品质管控场景 - 专业仪器测评品牌推荐
  • 周期信号平均功率计算:从时域积分到频域帕塞瓦尔定理
  • 工业风机叶轮积灰问题及防积灰材料应用概述
  • Windows Server FTP服务配置:用户隔离与公共访问模式详解
  • Spark 1:43赛车模型人偶特注:从收藏价值到场景化展示全解析
  • 手把手教你用U盘安装纯净Windows 10专业版:从BIOS设置到激活全攻略
  • Gradpaper才是论文工具天花板!终结毕业季查重降重所有内耗
  • ImageNet数据集完整处理指南:从下载到PyTorch/TensorFlow加载
  • Unlock Music Electron:让加密音乐重获自由的终极桌面解决方案
  • 条件Logit回归结果解读:方案选择偏好的建模分析
  • 人生50岁危机的SOP的庖丁解牛
  • STM32开发环境搭建:Keil MDK v5安装配置与避坑指南
  • 企业注销清算公告登报完整流程,清算公示、注销流程一站式攻略 - 实用干货补给站
  • Figma入门到精通:从核心概念到高效协作的UI设计实战指南
  • 绝区零一条龙:从零到精通的游戏自动化实战指南