22.7 Meltdown Fix

我最后想讨论的是Meltdown的修复,你们实际已经接触了一些了。当论文发表的时候,它获取了很多的关注。实际中还有另一篇论文,也是由这篇论文的部分作者参与完成,另一篇论文讨论了一种使用了CPU内一种叫做Spectre的不同的预测执行的不同攻击方法。这一对论文的同时出现让人非常兴奋( ̄▽ ̄)"。

所以人们现在发现危害太大了,因为现在我们讨论的是操作系统的隔离性被破坏了。这里的技术破坏了Page Table的保护,这是我们用来实现用户和内核间隔离的技术,所以这是一个非常基础的攻击,或者至少以一种非常通用的方式破坏了安全性非常重要的一个部分。所以人们非常非常迫切的想要修复Meltdown。

很多操作系统在这篇论文发表之后数周内就推出的一个快速修复,这是一个叫做KAISER,现在在Linux中被称为KPTI的技术(Kernel page-table isolation)。这里的想法很简单,也就是不将内核内存映射到用户的Page Table中,相应的就像XV6一样,在系统调用时切换Page Table。所以在用户空间时,Page Table只有用户内存地址的映射,如果执行了系统调用,会有类似于XV6中trampoline的机制,切换到拥有内核内存映射的另一个Page Table中,这样才能执行内核代码。

这会导致Meltdown不能工作,因为现在你会切换Page Table,本来代表内核虚拟内存地址的r1寄存器不仅是没有权限,并且也没有意义了,因为现在的用户Page Table并没有包含对它的翻译,所以CPU并不知道该如何处理这个内存地址。现在这个虚拟内存地址不会存在于cache中,甚至都不会出现在TLB中。所以当在用户空间发起Meltdown Attack时,也就没有办法知道对应这个虚拟内存地址的数据是什么。这个虚拟内存地址并不是非法的,只是在用户空间没有意义了,这样会导致Meltdown Attack不能工作。

KAISER的缺点是,系统调用的代价更高了,因为如果不做任何事情的话,切换Page Table会导致TLB被清空,因为现在TLB中的映射关系都是前一个Page Table的。同时也会导致L1 cache被清空,因为其中对应的虚拟内存地址对于新的Page Table也没有意义了。在一些机器上,切换Page Table会使得系统调用明显变慢。

最近的CPU拥有叫做PCID(process-context identifiers)的技术,它可以帮助你在切换Page Table时避免清空Cache,尽管它还是要花费一些时间。

如果你上网看的话,当时人们有很多顾虑,当时人们认为这种两个Page Table的方案是不可接受的慢。但是实际中这并不是一个严重的问题,你上网看的话就可以发现人们有对于工作负载的整体影响的评估,因为毕竟程序也不是一直在进出内核,这里的影响大概是5%,所以这并不是一个坏的主意。人们非常快的采用了这种方案,实际上在论文发表时,已经有内核采用了这种方案来抵御其他的攻击。

除此之外,还有一个合理的硬件修复。我相信Intel在最近的处理器上已经添加了这个修复,AMD之前就已经有这个修复。

这是Cache的结构,当指令从L1 cache中加载某个数据时,比如说我们想要窃取的内核数据,人们认为数据的权限标志位就在L1 cache中,所以CPU完全可以在获取数据的时候检查权限标志位。实际中,AMD CPU和最近的Intel CPU会在很早的时候检查权限标志位。如果检查不能通过,CPU不会返回数据到CPU核中。所以没有一个预测执行指令可以看到不该看到的数据。

学生提问:为什么你觉得Intel会做这个呢?对我来说这里像是个讨论,我们应该为预测执行指令检查权限标志位吗?Intel的回答是不,为什么要检查呢?

Robert教授:是的,为什么要检查呢?反正用户也看不到对应的数据。如果更早的做权限检查,会在CPU核和L1 cache之间增加几个数字电路门,而CPU核和L1 cache之间路径的性能对于机器来说重要的,如果你能在这节省一些数字电路门的话,这可以使得你的CPU节省几个cycle来从L1 cache获取数据,进而更快的运行程序。所以很容易可以想到如果过早的检查权限,会在电路上增加几个晶体管。因为毕竟所有的预测执行指令都会Retired,并不是说过早的检查权限就可以节省一些后续的工作,在指令Retired的时候还是要触发Page Fault。我这里只是猜测,这里做一些权限检测并不能带来什么优势。

学生提问:既然Intel已经从CPU上修复了这个问题,有没有哪个内核计划取消KAISER来提升性能?

Robert教授:我知道在很多内核上,这个是可选项,但是我并不完全清楚Intel修复的具体内容。我很确定他们有一些修复,但是具体内容我并不知道。

Frans教授:我认为Linux中你可以查询哪些硬件修复已经存在,并根据返回要求Linux修改从软件对于硬件问题的规避。你可以在你的笔记本上运行一个Linux命令来查看它包含了哪些问题的修复,哪些问题已经在硬件中规避了。

Robert教授:你是说如果CPU包含了修复的话,Linux实际会使用combined Page Table(注,也就是将内核内存映射到用户Page Table中)?

Frans教授:是的,我99%相信是这样的,虽然我最近没有再看过了,但是我认为还是这样的。

学生提问:人们是在干什么的时候发现这个的?

Robert教授:当人们尝试入侵一个计算机的时候。谁知道人们真正想要干什么呢?论文是由学院派写的,或许他们在研究的时候发现了一些安全问题。

Frans教授:我认为很长时间他们的一个驱动力是,他们想破解Address Space Layout Randomization,他们有一些更早的论文,看起来在这个领域有一些研究者。我认为最开始的时候,人们来自不同的领域。 就像Robert说过的,人们在这个领域工作了几十年来找到可以理解和攻击的Bug。

学生提问:有多大的可能还存在另一种Meltdown?

Robert教授:非常有可能。CPU制造商在几十年间向CPU增加了非常非常多酷炫的技术,以使得CPU运行的可以更快一些。人们之前并没有太担忧或者没有觉得这会是一个严重的安全问题。现在人们非常清楚这可能会是非常严重的安全问题,但是我们现在使用的CPU已经包含了30年的聪明思想,实际上在论文发表之前,已经存在很多基于Micro-Architectural的这一类攻击。我认为还需要一段时间才能把这一类问题完全消除。

Frans教授:如果你查看过去两年的安全相关的会议,每个会议基本都有一个session是有关探索预测执行属性,来看看能不能发起一次攻击。

Robert教授:或许这是一个更大的问题,是不是我们解决了有限的问题就没事了,又或者是上层设计方法出现问题了。这可能太过悲观了,但是你知道的,人们对于操作系统的隔离寄托了太多期望,可以非常合理的认为隔离可以工作。并且我们会在这种假设下设计类似于云计算,在浏览器中运行Javascript等等场景。但是现在这种假设实际并不成立,曾经人们认为操作系统的隔离性足够接近成立,但是这一整套基于Micro-Architectural的攻击使得这里的故事不再让人信服。

学生提问:CPU设计者可以做到什么程度使得不使用Micro-Architectural又能保持高性能,同时也有很好的安全性?

Robert教授:有些内容明显是可以修复的,比如这节课介绍的Meltdown Attack是可以被修复的,并且不会牺牲任何性能。对于一些其他的攻击,并不十分确定你可以在不损伤性能的前提下修复它们。有些问题隐藏的非常非常的深,现在有很多共享的场景,例如分时共享的计算机,云计算。假设在你的云主机上有一个磁盘驱动和一个网卡驱动,你或许可以仅仅通过监测别人的流量是怎么影响你的流量的,这里的流量包括了网络流量和磁盘流量,来获取同一个主机上的其他用户信息。我不知道这是否可行,但是对于很多东西,人们都能发现可以攻击的点。

所以很多这里的Micro-Architectural带来的问题可以在不损伤性能的前提下清除掉,但是也或许不能。

(中间有一段有关如何计算机攻击的讨论,无关故略过)

Last updated