Go Wiki: Spectre

概览

Go 1.15 增加了对启用代码生成调整的支持,以缓解 Spectre 系列 CPU 漏洞中两个变体的影响。编译器和汇编器都增加了一个新的标志 -spectre,用于指定要启用的 Spectre 缓解措施列表,例如 -spectre=index-spectre=index,ret。特殊情况 -spectre=all 启用所有可用的缓解措施。

index 缓解措施可以在编译器中启用,它会更改代码生成,以发出针对 Spectre 变体 1(“边界检查绕过”)的保护。该缓解措施通过在错误推测时将索引屏蔽为零,确保 CPU 不会访问任意内存。此更改通常会使执行速度降低约 5-10%;确切的减速取决于工作负载。

ret 缓解措施可以在编译器和汇编器中启用,它会更改代码生成,以发出针对 Spectre 变体 2(“分支目标注入”)的保护。此缓解措施将每个间接调用指令替换为使用 retpoline 小工具。此更改通常会使执行速度降低约 10-15%;同样,确切的减速取决于工作负载。

适用性

在撰写本文时,我们没有在 Google 运行的 Go 程序中使用这些缓解措施,也不打算这样做。它们被包含在 Go 工具链中,作为为具有非常特殊用例(或非常偏执)的用户提供的一种“深度防御”。

只有当 Go 程序可能受到 Spectre 攻击时,这些缓解措施才必要,这需要以下所有条件都为真。首先,攻击者必须能够在与包含秘密的受害 Go 程序相同的 CPU 上运行任意代码。其次,攻击者必须能够向受害 Go 程序发出某种 HTTP 或 RPC 请求。第三,这些请求必须触发潜在的脆弱代码片段,以推测到攻击者选择的行为。最常见的情况是使用任意攻击者提供的整数来索引切片或数组。这三个条件很少同时都为真。

示例

要构建一个在所有包中都启用了这两种缓解措施(以及任何未来的缓解措施)的程序,请使用

go build -gcflags=all=-spectre=all -asmflags=all=-spectre=all program

致谢

感谢 Andrea Mambretti 等人。在发表前分享了他们的论文(链接如下)。并感谢他们、Chandler Carruth 和 Paul Turner 提供的有益讨论。

参考

Spectre 攻击:利用推测执行
作者 Paul Kocher 等人。(权威论文。)

推测性缓冲区溢出:攻击和防御
作者 Vladimir Kiriansky 和 Carl Waldspurger。

Retpoline:一种用于防止分支目标注入的软件构造
作者 Paul Turner。

瞬态执行攻击和防御的系统评估
作者 Claudio Canella 等人。(变体的良好总结。)

Spectre 将持续存在:侧信道和推测执行分析
作者 Ross McIlroy 等人。(这些不会消失。)

Spectre 再次出现!使用返回栈缓冲区进行推测攻击
作者 Esmaeil Mohammadian Koruyeh 等人。(甚至返回预测也不安全。)

推测加载强化
作者 Chandler Carruth。(LLVM 为防止推测性越界访问所做的工作。)

通过推测性控制流劫持绕过内存安全机制
作者 Andrea Mambretti 等人。(对内存安全语言影响的检查。)


此内容是 Go Wiki 的一部分。