news 2026/5/23 17:48:34

X86 SMAP(Supervisor Mode Access Prevention)机制引入的内核态访问用户态地址空间的问题分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
X86 SMAP(Supervisor Mode Access Prevention)机制引入的内核态访问用户态地址空间的问题分析

在Linux系统中,当涉及到用户态和内核态数据拷贝的时候,如果不考虑建立kernel space和user space的共享映射实现的零拷贝情况(内核和用户态各自映射,持有同一个BUF的不同指针的情况),一般是调用copy_from_user/copy_to_user/put_user/get_user几组宏来实现的。在早些时候,对于内核中访问的用户态指针非法(没有VMA区域)或者缺页(有VMA但是MMU没有建表映射)两种情况,在函数实现中使用修复表进行处理,修复表寄生在PAGE FAULT执行流程中,第一种情况下修复表会返回错误码,第二种情况则通过page fault流程建立到物理PFN的映射,接着返回到触发FAULT的指令重新执行,指令自然成功完成,否则,再进入修复表流程进行错误处理。而对于合法的已映射的用户态指针,则直接在内核中访问即可。所以,从内核中可以直接访问当前进程的用户空间,使用的虚拟地址也与当前进程处于用户空间时的地址完全相同。反之(用户空间访问内核空间指针)则不允许。

但是这个结论似乎在运行最新linux的 x86 平台上遇到了反例,即便在内核中访问合法的用户态地址,也会被禁止,做个实验:

在设备驱动中直接读取用户态传递下来的buf指针的内容:

运行用户态用例,发现测试进程被KILL,内核报告permission违例。

仔细分析出错LOG,发现出错原因是#PF: error_code(0x0001) -permissions violation,许可违例。分析现场,发现出错地址0x7ffc922277b0和内核report的fault地址是一致的,并且,此虚拟地址对应的四级页表都有映射(PGD 23144d067 P4D 23144d067 PUD 2315d8067 PMD 23b0e9067 PTE, P4D和PGD重合)。也就是说,被访问的虚拟地址既不是非法地址,页表也没有缺页,它是一个合法的用户态地址,按照本文开头的分析结论,此地址应该能够被内核安全访问才对,但是却报错了。

原因分析:

出现这个问题的原因和硬件架构和内核版本都有关系,最根本的原因是CPU硬引入了一个新的功能引起的,在最新的X86处理器的CR4寄存器中,引入了SMEP和SMAP 控制BIT,用来配置内核对用户态地址空间的访问权限。SMAP(Supervisor Mode Access Prevention)是Intel从Haswell微架构开始引入的一种新特征,它在CR4寄存器上引入一个新标志位SMAP,如果这个标志为1,内核访问用户进程的地址空间时就会触发一个页错误,目的是为了防止内核因为自身错误意外访问用户空间,这样就可以避免一些内核漏洞所导致的安全问题.但是由于内核在有些时候仍然需要访问用户空间,因此intel提供了两条指令STAC和CLAC用于临时打开/关闭这个功能,反复使用STAC和CLAC会带来一些轻微的性能损失,但考虑到增加的安全性,还是建议开启.

SMEP:位于Cr4的第20位,作用是让处于内核权限的CPU无法执行用户代码.作用是阻止内核执行用户页。无法执行用户空间。
SMAP:位于Cr4的第21位,作用是让处于内核权限的CPU无法读写用户代码.作用是阻止内核对所有用户页的数据读写访问,无论该页存的是代码还是数据。无法读写用户空间。

可以通过如下命令查看CPU是否支持smap功能,如下图所示,我的8核处理器每个核心都支持SMAP。

$ sudo cpuid|grep -i smap

另一台12核AMD处理器SMAP支持情况

启动不支持SMAP虚拟机系统(通过传入QEMU命令限制VCPU的能力),所以在虚拟机中进行内核直接访问用户态指针的测试是成功的。

内核中有配置选项CONFIG_X86_SMAP用来启用或者关闭SMAP功能,默认情况下是打开的.

那么为什么通过copy_from_user/put_user宏可以安全访问用户态指针呢?

以get_user为例,其它宏定义实现类似,在get_user的核心实现__get_user_1中,在进行真正的用户态指针访问前后,程序调用了ASM_STAC/ASM_CLAC去打开/关闭内核访问用户地址空间权限的功能:

并且在标号1处的修正表实现中也调用了CLAC指令对SMAP功能进行了控制,所以get_user才能安全地访问用户地址空间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 17:46:03

Bifrost三星固件下载器:跨平台免费下载官方固件的终极指南

Bifrost三星固件下载器:跨平台免费下载官方固件的终极指南 【免费下载链接】Bifrost Cross-platform tool for downloading Samsung mobile device firmware. 项目地址: https://gitcode.com/gh_mirrors/sa/Bifrost 还在为三星设备固件下载的复杂流程而烦恼吗…

作者头像 李华
网站建设 2026/5/23 17:46:01

欢迎使用MDVideo

欢迎使用MDVideo 【免费下载链接】mdvideo Markdown To Video, 一个将markdown文档转为视频的便捷工具 项目地址: https://gitcode.com/gh_mirrors/md/mdvideo 这是一个演示视频 fontFamily新叶念体 color#00C8D1 positioncenter ### 第三步:实时预览与调整…

作者头像 李华
网站建设 2026/5/23 17:43:29

3大技术革命:openpilot如何重新定义自动驾驶开源生态

3大技术革命:openpilot如何重新定义自动驾驶开源生态 【免费下载链接】openpilot openpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars. 项目地址: https://gitcode.com/GitHub_Trending…

作者头像 李华
网站建设 2026/5/23 17:40:08

MakeMeAHanzi:免费开源的汉字数据宝典完整指南

MakeMeAHanzi:免费开源的汉字数据宝典完整指南 【免费下载链接】makemeahanzi Free, open-source Chinese character data 项目地址: https://gitcode.com/gh_mirrors/ma/makemeahanzi MakeMeAHanzi是一个强大的免费开源汉字数据项目,为开发者、教…

作者头像 李华