为什么 CPU 的设计方式使“崩溃”漏洞得以发挥作用?

信息安全 崩溃
2021-08-20 13:34:25

我正试图围绕“崩溃”展开我的头脑,但首先要理解它,我一直在尝试理解内存访问。

据我了解,CPU 尝试在转换后备缓冲区中查找虚拟地址,该地址指示 CPU 缓存中的数据。如果它在那里,我们立即获取它。如果没有,我们然后在页表中查找地址。

现在从我的阅读来看,每个进程都有自己的页表。但是,每个进程也将内核映射到它的页表中。

大概页表也有访问位,显然我们不能在 CPU 处于用户模式时允许直接读取内核空间(我认为这称为“ring-3”)。

根据我对页表的了解,这些访问位存储在地址的低位中。由于我们的页面条目是 4k,因此还有很多位用于存储访问位。

从我读到的关于漏洞利用的内容来看,问题是在检索数据后检查访问权限。这样做的原因是出于效率原因,我们希望快速将数据发送到 CPU,并且我们可以在进行任何永久性更改之前捕获权限错误。但不幸的是,我们通过使用定时攻击可以检测到的间接内存获取影响了 CPU 缓存。

如果页面查找成本低但访问检查成本高,则此方案可能有意义。但根据我的理解,情况似乎并非如此。

我读过 64 位机器上的页表至少有三层,这意味着至少有三个内存查找。希望这些在缓存中,但如果不是,则意味着递归搜索页表以查找它自己的页面。

在我们做完这一切工作,终于找到了页表项之后,当我们从页表中加载物理地址的时候,我们也加载了访问位。为什么不在那里检查呢?检查我们已经加载的访问位似乎比使用电路来处理它要简单得多。

我显然错过了关于 CPU 工作方式的一些信息,但我无法弄清楚是什么。我们必须进行页表查找才能确定要获取的内容,一旦我们遇到了麻烦,为什么不检查访问位呢?

2个回答

你错过了几件事:

  1. 有问题的内核内存可能已经在缓存中,使得获取数据的速度与获取访问位一样快。这是两者的内容寻址查找。即使没有,也有 TLB。当以性能为目标时,完整的三级页表访问不是优化的常见情况。

  2. 特权级别本身可能会被管道中的其他半执行指令更改。在这些指令完全退役之前,特权级别本身只是一种推测。

我想知道#2 是否会导致发现更多漏洞……

真正的原因是没有人在设计过程中意识到安全问题。没有根本原因不能安全地实施 CPU,您的问题概述了一种方法。

推测执行是为了性能,因此 CPU 在实际执行之前会尝试做尽可能多的工作,但它不能修改“架构状态”——软件可以看到的内容。将内存加载到内部缓冲区不会影响状态,因此它可以在需要时这样做。但是导致访问冲突确实会影响它,因此当前的设计要等到实际执行。(这是我的一些猜测)。

尽管 AMD 不易受到 Meltdown 的影响,但我怀疑这比计划更幸运。Meltdown 论文称,英特尔和 AMD 在访问违规后都会执行推测性查找。他们只是无法对 AMD 进行实际利用。

一个合理的解决方法是在推测性查找之前检查权限,并在推测性执行发生时停止推测性执行。当实际执行赶上时,它可以引发中断并避免留下任何站点影响。