阅读白皮书,听起来像是厄运和悲观。主网页指出“Spectre 比 Meltdown 更难利用,但也更难缓解。但是,可以通过软件补丁阻止基于 Spectre 的特定已知漏洞。”
这似乎意味着不可能通过软件补丁来防止基于 Spectre 的未知攻击,是这样吗?
阅读白皮书,听起来像是厄运和悲观。主网页指出“Spectre 比 Meltdown 更难利用,但也更难缓解。但是,可以通过软件补丁阻止基于 Spectre 的特定已知漏洞。”
这似乎意味着不可能通过软件补丁来防止基于 Spectre 的未知攻击,是这样吗?
Spectre 攻击的核心是利用 CPU 的分支预测器的错误训练,使 CPU 在执行目标程序时推测性地分支到攻击者选择的代码片段,然后观察运行该代码的间接影响。这是唯一可能的,因为当前 CPU 在计算机上运行的所有线程之间共享分支预测器状态。
可以通过在每个分支之后插入防止推测执行的指令(例如cpuid
ormfence
指令)来编写不受 Spectre 影响的 x86/amd64 代码,但这是以相当严重的性能损失为代价的,并且只能应用于新软件。
通过重置每个上下文切换的状态(以牺牲一些性能为代价),可以使允许刷新分支预测器状态的 CPU 免受 Spectre 的影响。英特尔和 AMD 的 x86/amd64 架构的实现似乎都没有这样的指令(目前),但我预计它会在几年内出现。与防止推测执行相比,这对性能的影响要小得多,因为即使是未初始化的分支预测器也有大约 70% 的准确率。
这里有两种不同的情况。一种是在 CPU 上运行不受信任的机器代码。另一种是在 JIT 编译器(例如 Javascript)中运行不受信任的字节码或脚本。
编辑:由于我对 Spectre 用来正常工作的代码的误解,我改变了一些东西。它使用具有更高权限的现有代码和条件分支,其中故意使 CPU 执行分支中的错误路径,并向其提供恶意数据,这导致内存读取被缓存然后被丢弃。除了概念验证代码之外,漏洞利用程序使用系统上已经存在的代码,而不是我之前说的它自己的代码。
Meltdown 与在受限环境(例如受限用户帐户)中在 Intel CPU 上运行不受信任的机器代码有关。该代码可以使用 Meltdown 访问受读取保护的内存,例如应该是禁区的内核内存。它与 JIT 编译器无关。
Spectre 与: 1) 像 Meltdown 一样,在受限环境中运行不受信任的机器代码并访问受限内存,例如内核内存。可以访问的内容取决于运行 Spectre 易受攻击的代码时映射到虚拟地址空间的内容。2) JIT 编译器,例如 Javascript。Spectre 可以利用运行不受信任代码的 Javascript 和其他 JIT 编译受限环境来访问 Javascript JIT 编译器、浏览器的地址空间,可能还不止这些。
在 JIT 编译器或解释器中运行的代码的优点是只需要对 JIT 编译器或解释器进行补丁来解决问题。使攻击脚本无法探测缓存可以击败 Spectre。我相信对 Spectre 进行本地代码修补是比较困难的地方。
用于修复 Meltdown 的页表隔离补丁无法修复 Spectre*。Spectre 易受攻击的代码是系统上已经存在的条件代码。为了利用 Spectre,此代码以与攻击程序不同的权限运行,因此它可以访问攻击程序无法访问的数据。在攻击程序准备好缓存并对分支预测器进行错误训练后,攻击程序会调用 Spectre 易受攻击的代码,并使用参数导致其推测执行的指令从它通常保护的内存中读取。这些读取指令永远不会被 CPU 完全执行,因为一旦发现分支预测错误,它就会转储它们。但是读取操作会影响缓存,现在攻击程序会分析缓存以查找数据。
所以是的,可以制作软件补丁。一旦发现易受攻击,可以修改个别条件,使其对 Spectre 无用。在所有分支指令之后添加机器代码的更通用方法可以使 CPU 不推测性地执行任何操作。这将导致显着的性能影响,因为现代 CPU 在等待验证分支预测时可以推测性地执行 100 多条指令!也许可以进行某种编译器修改,以使其在基于用于条件的变量的值访问数据或基于外部数据的内存访问的条件之后禁用推测执行,或者它可能要求条件中使用的变量是存储在寄存器中以保证启用推测执行。
*我在这里所说的涉及对 Spectre 易受攻击代码可读区域的内存访问。我还不知道投机执行的指令是否可以像 Meltdown 那样访问受读保护的数据。也许这在 Intel CPU 而不是 AMD 上是可能的?我怀疑没有太多关于这个的讨论,因为大多数 CPU 都是英特尔,任何易受 Spectre 攻击的英特尔也易受 Meltdown 攻击。但是对于在 JIT 编译器中运行的不受信任的代码可能很重要,因为这样的代码将可以访问 JIT 编译器地址空间(内核和物理内存)的受读保护部分,同时使用以以下权限运行的 Spectre 易受攻击的代码JIT 编译器。页表隔离补丁可以解决这个问题,但用户可能会认为,因为他们不是