[翻译]神秘的Linux页表隔离(PTI)补丁
译者注:2018新年伊始,一个影响Intel CPU的严重漏洞就被曝光,这个漏洞可以导致用户空间代码读取内核空间的内存信息。一位名叫"python sweetness"的用户发布了一篇介绍文章,这里我们将其翻译为中文,以便国内的用户能够更好地理解。
简要介绍: 最近,一个几乎影响了所有实现虚拟内存机制的CPU的安全漏洞被发现,而这个漏洞需要从硬件层面修复才能完全解决。在软件层面上,Linux内核的修复正在紧急地进行中,Windows NT内核的修复也在11月开始。但是,软件层的修复在最差情况下会造成严重的系统运行放缓。这种攻击会影响包括Amazon EC2和Google Compute Engine在内的常见虚拟化环境;另外,还有信息指出,这类攻击可能涉及一个新的Rowhammer变种。
一般来说,我对安全问题是不太在意的,但是最近我深深迷上了一个小谜团。不过,那些通常都会详细介绍这个话题的人好像都很忙,或者虽然已经知道细节但没有公布。所以,我在新年第一天,花了几个小时里来挖掘关于这个谜团尽可能多的信息。
值得注意的是,这件事很像是连点游戏,所以直到细节真相大白,所做的主要还是以猜测为主。不过,从我(当然也包括涉及的厂商)目前所知道的来看,那一天到来的时候,是要搞个大事情了。
LWN
首先,我们从12月20日在LWN发布的文章《内核页表隔离(page-table isolation)的现状》开始。从文章中可以看出,核心内核开发人员已经在KAISER补丁的相关紧急工作上投入了大量精力。
KAISER是由奥地利格拉茨大学(TU Graz)的一组研究人员在10月份首次公布的,它的概念并不复杂:当进程在用户空间中运行时,将Linux内核尽可能地从进程页表中unmap掉,从而极大地阻碍了用户空间的非特权代码识别内核虚拟地址范围的尝试。
在该研究小组的文章《KASLR已死:KASLR不朽》的摘要中,特别提到了当CPU在执行用户空间代码时,在内存管理单元中清除内核地址空间的全部信息这一措施。
有趣的是,虽然这个补丁集涉及了内核及其与用户空间接口的基础,但其立刻被提升到了最高的优先级并进行处理。与之相对的,如果查阅之前Linux内存管理的变更就可以看到,当一个变更代码真正被合并时,往往距离其第一次被提出之后已经很久了,在这之间通常是多轮的审查,回绝和争论,耗时漫长。但是,KAISER(即现在的KPTI),只用了不到3个月的时间就被合并了。
背景回顾:ASLR
从表面上看,KAISER补丁的设计目的,是确保地址空间布局随机化保持有效。ASLR是现代操作系统的一项安全功能,其试图将尽可能多的随机位引入映射对象的地址范围。
例如,在调用/usr/bin/python(从上下文看,这里应该是bash)时,动态链接器会负责将系统C库,堆,线程栈和可执行文件分配到随机指定的地址范围中:
$ bash -c 'grep heap /proc/$$/maps'
019de000-01acb000 rw-p 00000000 00:00 0
$ bash -c 'grep heap /proc/$$/maps'
023ac000-02499000 rw-p 00000000 00:00 0
可以看到,随着每次运行,bash进程的堆的地址范围也是在变化的。
ASLR的效果如下:如果某个缓冲区管理有问题,导致攻击者能够覆盖一些指向程序代码的内存,并且其在稍后的执行时会被使用,那么攻击者就可以篡改控制流,从而跳转到另一块他们所控制的缓冲区;但是,ASLR可以使得攻击者用机器代码填充缓冲区并执行特定方法(例如system()这一C库函数)变得更加困难,因为函数的地址在每次运行时是不固定的。
上面提到的只是一个简单的例子,ASLR旨在保护许多类似的情况,包括防止攻击者获知程序数据的地址,而这些地址对于修改控制流或实施攻击可能是有用的。
KASLR则是“简单地”将ASLR应用于内核本身:当系统每次重启时,属于内核的地址范围是随机的。因此,如果攻击者在内核模式下尝试修改控制流并实施攻击(例如查找当前的进程数据、将非特权用户切换到root用户等),那么攻击者将无法猜测到所需的函数和结构体的地址。
坏消息:软件修复的代价很大
将内核内存映射到与用户内存相同的页表中的旧Linux行为的主要原因是,当用户代码触发系统调用,故障或中断时,不需要更改虚拟内存布局正在运行的过程。
由于没有必要更改虚拟内存布局,因此不需要刷新高度依赖于该布局的对性能高度敏感的CPU高速缓存,主要是转换检测缓冲区。
随着页表拆分补丁的引入,每当CPU运行状态改变时(包括从用户态切换到内核态以及从内核态切换到用户态),内核就需要刷新这些缓存。这将导致对于一些计算工作,TLB的有效预测将大大下降,这部分的损失将导致CPU效率的明显下降。感谢@grsecurity为我们实际测量了一个例子:该测量中Linux系统的“du -s”命令的执行效率在一个AMD的CPU上降低了50%!
34C3
在今年的CCC上,你可以找到另外一个TU Graz的研究人员描述一个纯粹的Javascript对ASLR进行的攻击。该攻击通过仔细测量CPU内存管理单元遍历描述虚拟内存布局的页表时的运行时间。其效果是通过CPU高速缓存行的高精度时序和选择性逐出的组合,运行在Web浏览器中的Javascript程序可以恢复Javascript对象的虚拟地址,从而实现对浏览器内存管理问题的后续攻击。
于是现在我们整理一下思路:有一个团队正在抓紧时间拼命编写KAISER补丁程序。最近还出现了一个可以立刻在计算机中实现对抗ASLR的技术。
背景回顾:虚拟内存
在通常情况下,当一些机器代码尝试加载,存储或跳转到内存地址时,现代CPU必须首先将这个虚拟地址转换为物理地址,通过一系列由操作系统管理的数组(通常称其为页表)描述了机器中安装的虚拟内存和物理RAM之间的映射。
虚拟内存可能是现代操作系统中最重要的鲁棒性机制:例如,它可以防止一个卡死的进程将整个操作系统弄崩溃,防止因为网页浏览器的错误而导致用户桌面环境的崩溃,或防止在Amazon EC2中运行的虚拟机影响同一主机上的另一个虚拟机。
对这一机制的攻击正是建立在CPU维护大量缓存这一事实上的。攻击者通过仔细地操纵这些缓存的内容,可以推断内存管理单元在走过各级页表时访问的是哪些地址,因为未缓存的访问将比缓存的访问花费更长时间。通过检测页表的哪些元素被访问,就有可能恢复大部分在内存管理单元管控下的地址。
有了动机,但似乎还不够
我们已经找到了发布本次补丁的动机,但是到目前为止,我们还没有看到任何能证明这次次事件背后内核开发者们巨大恐慌的证据。一般而言,ASLR是一种不完美的缓解措施,也是最后一道防线:从ASLR存在开始,即使是个安全小白也只需要不到6个月就能掌握各种关于ASLR的最新攻击方法。
如果仅仅只是为了修复ASLR的话是完全不需要像这次事件中体现出的这么高的工作优先级的。这次补丁修复的急切程度都表明了这背后一定有更大的安全问题。
证据:存在一个硬件安全的漏洞!
在阅读大量该系列补丁后,一些事情就开始明朗了。
首先,正如@grsecurity所指出的那样,尽管代码中的一些注释已经被编辑,但是这项修复工作的主要文档文件却一直在Linux代码树中被遗漏。应该是有意为之。
然后我们来看看补丁代码:
检查代码时,只有在内核检测到系统受到影响时,才会以计算机boot阶段的运行时修补程序的形式进行修复,且该修复和当初针对发生在奔腾处理器上臭名昭着的Pentium F00F错误的修复方式一模一样,因此显然这是个处理器上的硬件问题!
更多线索:微软也实现了页表隔离
通过浏览FreeBSD的源码发现,似乎到目前为止其他的开源系统仍未实现页表隔离,然而Alex Ioniscu在推特上提到,这项工作不仅仅局限于Linux:NT内核于11月份就开始实现相同的技术。
猜测:Rowhammer
进一步挖掘TU Graz研究人员的工作,我们发现Rowhammer只发生了一次,在12月4日发布了一个新的“Rowhammer”攻击变种的公告:
在这篇文章中,我们提出了新的Rowhammer攻击和利用,表明所有防御方式的组合均无效。我们新的攻击技术,“one-location hammer”打破了对触发Rowhammer漏洞触发条件以往的假定。
作为一个快速回顾,Rowhammer是一类针对大部分(所有?)商业DRAM的基本问题。比如普通计算机的内存,通过对内存一个区域的精确操作,有可能导致存储器的相关区域(但逻辑上不同)区域的存储性能下降。影响是Rowhammer可以用来翻转非特权用户代码不可访问的比特位,这些比特位控制了代码对系统其它部分的访问。
我发现在Rowhammer上这个工作特别有趣,尤其是因为它的版本与页表隔离补丁非常接近。但是因为Rowhammer攻击需要一个目标:你必须知道你试图改变的内存的物理地址,学习物理地址的第一步可能是学习虚拟地址,正如在KASLR揭密工作描述的那样。
猜测:它影响主要的云提供商
从核心邮件列表我们可以看到,除了系统维护人员的名字,Intel,Amazon,Google雇员的邮箱地址也赫然在列。两家最大云提供商的出现十分有趣,这给我们提供了强有力的线索,说明这项工作很大部分由虚拟化安全驱动的。
这引发了更多的猜测:虚拟机内存和虚拟机所使用的虚拟内存地址最终表现为宿主机上大量连续的阵列。尤其在只有两个租户的宿主机上,由Xen和Linux内核的内存分配器所分配的阵列很可能有可预测的行为。
最喜欢的猜测:这是对hypervisors的特权提升攻击
总的来说,我并不感到惊讶,如果我们开启2018在这种情形下,很多的hypervisor特权提升漏洞的公布,或者驱动如此紧迫的类似系统性的东西,以及补丁集CC列表上很多有意思名字的出现。
最后一点,尽管我并没有通读补丁,但有些代码明确标识了半虚拟化或者Xen不受影响。
预测:2018会很有趣
这种猜测完全有可能与现实相差甚远,但有一件事是可以确定的,无论这件事发表了什么,那时将是兴奋的几周。