跨线程返回地址预测¶
某些 AMD 和海光处理器容易受到跨线程返回地址预测漏洞的影响。当在 SMT 模式下运行时,并且一个兄弟线程转换出 C0 状态时,另一个兄弟线程可以使用从转换出 C0 的兄弟线程返回的目标预测。
Spectre v2 缓解措施保护 Linux 内核,因为它在上下文切换到空闲线程时,用安全目标填充返回地址预测条目。但是,KVM 允许 VMM 在转换出 C0 时阻止退出访客模式。这可能导致访客控制的返回目标被兄弟线程使用。
受影响的处理器¶
以下 CPU 容易受到攻击
AMD Family 17h 处理器
海光 Family 18h 处理器
问题¶
受影响的支持 SMT 的处理器在启用 SMT 时支持 1T 和 2T 执行模式。在 2T 模式下,核心中的两个线程都在执行代码。为了使处理器核心进入 1T 模式,需要其中一个线程请求转换出 C0 状态。这可以通过 HLT 指令或请求非 C0 的 MWAIT 指令进行通信。当线程重新进入 C0 状态时,处理器会转换回 2T 模式,假设另一个线程也仍在 C0 状态。
在受影响的处理器中,返回地址预测器 (RAP) 根据 SMT 模式进行分区。例如,在 2T 模式下,每个线程使用私有的 16 条目 RAP,但在 1T 模式下,活动线程使用 32 条目 RAP。在 1T/2T 模式之间转换时,RAP 内容不会被修改,但 RAP 指针(控制用于预测的下一个返回目标)可能会发生变化。此行为可能会导致一个 SMT 线程的返回目标在 1T/2T 切换后被兄弟线程中的 RET 预测使用。特别是,在转换到 1T 后立即执行的 RET 指令可能会使用刚刚变为空闲的线程的返回目标。从理论上讲,如果使用的返回目标不是来自可信代码,这可能会导致信息泄露。
攻击场景¶
可以通过执行一系列具有目标返回位置的 CALL 指令,然后转换出 C0 状态,在受影响的处理器上发起攻击。
缓解机制¶
在进入空闲状态之前,内核上下文切换到空闲线程。上下文切换通过执行一系列 CALL 指令,使用安全目标填充 RAP 条目(在 Linux 中称为 RSB)。
通过拦截 HLT 和 MWAIT 指令,防止访客虚拟机直接将处理器置于空闲状态。
需要两种缓解措施才能完全解决此问题。
内核命令行上的缓解控制¶
使用现有的 Spectre v2 缓解措施,这些措施将在上下文切换时填充 RSB。
KVM 的缓解控制 - 模块参数¶
默认情况下,KVM 虚拟机监控程序通过拦截访客尝试转换出 C0 来缓解此问题。VMM 可以使用 KVM_CAP_X86_DISABLE_EXITS 功能覆盖这些拦截,但由于这并不常见,因此默认情况下不会启用涵盖此路径的缓解措施。
可以使用布尔模块参数 mitigate_smt_rsb 开启对 KVM_CAP_X86_DISABLE_EXITS 功能的缓解,例如 kvm.mitigate_smt_rsb=1
。