暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

处理器特权模式下的访问限制

术道经纬 2019-05-04
115

操作系统的设计人员和硬件设计人员通常倾向于考虑如何保护内核空间免受用户空间进程的影响,整个系统的安全性取决于该保护。其实从内核保护用户空间也是有价值的。

除了一些特殊的内存配置外,内核的内存总是被映射的,因此理论上用户空间代码可以读取和修改它,但页面保护设置禁止了这种访问。用户空间检查或修改内核地址空间的任何尝试都将触发segmentation violation(SIGSEGV)信号。反方向的访问受到的控制则较少:当处理器处于内核模式时,它可以访问页表中所有的有效地址。处理器通常不会允许对只读存储区域进行写操作,但在需要的时候其实也可以越过这条规则。

2014年Intel Broadwell微架构中引入的的“Supervisor Mode Access Proteaction”(SMAP)功能改变了这种情况,该扩展在CR4控制寄存器中定义了一个新的SMAP位。设置该位后,在特权模式下运行时访问用户空间内存的任何尝试都将导致page fault。

当然,有时内核是需要使用用户空间内存的。为此,intel在EFLAGS/RFLAGS寄存器中定义了一个单独的“AC”(Access Control)标志位来控制SMAP功能。如果设置了AC标志位,则SMAP保护有效,否则允许访问用户空间内存。两个新指令STAC(Set AC Flag)和CLAC(Clear AC Flag)被用来相对快速地操纵该标志位(对,这就是cisc的风格,专有指令多一些,执行稍快一些)。

说到开销,对此功能的支持显然会付出一定的代价。用户空间访问功能(比如copy_to_user() 和copy_from_user()函数)往往是inline展开的,因此内核中会充斥着大量的STAC和CLAC指令。如果SMAP功能未被使用(要么是内核不支持,要么是被nosmap启动标志位禁用),可以使用一个替代机制,但内核的大小还是会增加一点。 此外,STAC和CLAC指令也需要一点时间来执行。

内核将处理SMAP violations,就像处理任何其他错误的指针访问一样,结果将是一个oops。既然内核自己可以随意关闭它,那这种保护的价值到底是什么。答案是它可以阻止一类漏洞,其中内核被错误地读取(或写入)用户空间内存。几年前暴露的null pointer漏洞集就是一个明显的例子。在很多情况下,攻击者已经找到了让内核使用bad pointer的方法,而攻击者可以在内核空间中执行任意代码(在利用bad pointer之前)的情况已经不那么常见了。SMAP应该可以很好地阻止类似的攻击。以前的内核都是严于待人(用户空间的进程),宽以律己的,这一漏洞被利用后也学会严于律己了。

当然,另一个好处就是查找内核错误。驱动程序的开发者(应该)知道他们不能直接从内核中dereference用户空间的指针,但是这样做的代码在某些体系结构上依然可以工作。启用SMAP后,这样的坏代码可以在进入内核mainline之前,被及早的发现和修正。通常情况下,让系统强制执行开发人员应遵循的规则是有实际价值的。

以上翻译自:lwn.net/Articles/517475,并经过适当调整。

H. Peter Anvin在linux内核中实现了对SMAP的支持,并merge进了3.7版本,对于支持此特性的处理器,之后都默认打开这一功能。

与之类似的一个指令SMEP(Supervisor Mode execution Proteaction)是在2012年代 Intel Ivybridge微架构引入的。SMEP可用于特权模式(内核空间)无意中执行用户空间代码, SMAP将此保护扩展到读和写。


文章转载自术道经纬,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论