Linux 内核 Cross-Thread RSB(CVE-2022-27672)漏洞机理剖析与 KVM/内核缓解配置指南
本文以内核文档 Documentation/admin-guide/hw-vuln/cross-thread-rsb.rst 为骨架,结合 x86/KVM 源码剖析 AMD/Hygon 处理器上的 Cross-Thread Return Address Predictions(跨线程返回地址预测,别名 SMT 相关的 RSB 预测注入,CVE-2022-27672)漏洞,说明其 RAP/RSB 硬件机理、攻击面,以及 Linux 内核对空转(idle)路径与 KVM 客户机的两级缓解机制与开关方法。读完本文,你将掌握该漏洞为何需要“内核 RSB 填充 + KVM 拦截 HLT/MWAIT”双管齐下、如何在命令行与 KVM 模块参数上正确配置,并能在源码层面追踪对应的实现路径。
漏洞概述与威胁模型
Cross-Thread Return Predictions(跨线程返回地址预测) 是一类影响特定 AMD 与 Hygon SMT 处理器的分支预测侧信道问题。当系统以 SMT 模式运行、且某个核心内的一对兄弟线程(sibling thread)之一通过 HLT 或 MWAIT 退出 C0 状态时,仍处于活跃状态的另一个兄弟线程 可能错误地消费已退出 C0 线程的返回目标预测,从而在 RET 预测路径中引入不可信地址。
Linux 内核本身通过 Spectre v2 缓解体系保护了这一路径:内核在上下文切换到 idle 线程(进入空转)时,会用安全目标填充返回地址预测表项。但 KVM 允许 VMM 在客户机退出 C0 时不退出 guest 模式,一旦 HLT/MWAIT 被允许直接在客户机内执行,就可能在兄弟线程的 RET 预测中混入由 guest 控制的目标——这正是漏洞需要被单独关注的原因。
受影响处理器
依据文档与 x86 源码中的漏洞黑名单,受影响处理器如下:
| 厂商 | 处理器家族 | 漏洞标志 |
|---|---|---|
| AMD | Family 17h | X86_BUG_SMT_RSB |
| Hygon | Family 18h | X86_BUG_SMT_RSB |
内核通过 arch/x86/kernel/cpu/common.c 中 cpu_vuln_blacklist 的条目 VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO | VMSCAPE) 与 VULNBL_HYGON(0x18, ...) 标记这些处理器,并在启动早期通过 cpu_matches(cpu_vuln_blacklist, SMT_RSB) 命中后执行 setup_force_cpu_bug(X86_BUG_SMT_RSB)(见 common.c)。该 bug 标志是整个缓解逻辑(含 KVM 模块参数生效判定)的分发开关,后续所有 boot_cpu_has_bug(X86_BUG_SMT_RSB) 检查都依赖它。
关联 CVE
| CVE | 名称 |
|---|---|
| CVE-2022-27672 | Cross-Thread Return Address Predictions |
该 CVE 与“SMT Retbleed”密切相关:受影响 CPU 同时携带 RETBLEED | SMT_RSB 等黑名单标志,属于同一代返回地址预测侧信道问题家族。
硬件机理:SMT 1T/2T 模式下的 RAP 分区与指针漂移
要理解该漏洞,需要先理解受影响处理器的执行模式切换机制:
- 支持 SMT 的受影响处理器在 SMT 使能时支持 1T 与 2T 两种执行模式:
- 2T 模式:核心内两个线程同时在执行代码;
- 1T 模式:仅单个线程活跃,要求另一个线程主动请求退出 C0 状态(通过执行
HLT指令,或执行请求非 C0 状态的MWAIT指令来表达)。当线程重新进入 C0 时,只要另一线程仍处于 C0,处理器便回到 2T 模式。
- 受影响处理器的返回地址预测器(Return Address Predictor,RAP) 依据 SMT 模式被分区使用:
- 2T 模式下,每个线程使用一份私有的 16 项 RAP;
- 1T 模式下,活跃线程使用 32 项 RAP。
- 关键点在于:1T/2T 模式切换时 RAP 内容并不清空,但控制“下一次 RET 预测该使用哪个返回目标”的 RAP 指针可能发生变化。
正是“内容保留、指针漂移”的组合,导致一个 SMT 线程的返回目标可能被兄弟线程的 RET 预测使用:RET 指令若紧跟在 1T 模式切换之后执行,可能消费刚从 C0 退出(转入 idle)线程留下的返回目标。理论上,若这些被消费的返回目标并非来自可信代码,就会造成信息泄露。Linux 文档将该硬件单元称为 RAP,而 Linux 上下文切换填充路径沿用了传统术语 RSB(Return Stack Buffer),二者在本文语境中指代同一预测结构。
攻击场景
攻击者可以在受影响处理器上按如下步骤布设攻击原语:
- 执行一系列 CALL 指令,把精心选择的“返回位置”(return locations)压入 RSB/RAP;
- 通过
HLT/MWAIT退出 C0 状态,触发 1T/2T 模式切换; - 借助 RAP 指针漂移,使兄弟线程随后的 RET 预测命中攻击者布置的返回目标。
若该返回目标落在攻击者可控制的代码(例如 guest 内代码)上,兄弟线程(宿主侧)可能在此后基于不可信预测执行,进而引发信息泄露。由于返回目标本身来自执行过的 CALL 指令,这一场景更偏向于推测执行窗口内的侧信道利用。
缓解机制:为何需要“内核 + KVM”双重防护
文档明确指出,完整解决该问题需要同时具备两层缓解:
1. 内核侧:idle 路径的 RSB 填充
在进入空转状态前,内核会把上下文切换到 idle 线程;上下文切换通过执行一串 CALL 指令,把 RAP/RSB 表项填充为安全目标。这样即便发生 1T/2T 切换、RAP 指针发生漂移,兄弟线程随后消费到的返回目标也来自内核植入的安全地址,而非前一线程遗留的用户可控地址。这一机制是既有 Spectre v2 缓解的一部分,其命令行为解析与缓解策略选择实现在 arch/x86/kernel/cpu/bugs.c(含 spectre_v2_user_parse_cmdline 等解析函数)。因此,只要保持 Spectre v2 缓解开启,宿主内核的上下文切换路径即处于受保护状态;相关的 RSB(返回栈缓冲)攻击与填充原理可进一步参考 Documentation/admin-guide/hw-vuln/rsb.rst。
2. KVM 侧:拦截 HLT 与 MWAIT,阻止 guest 直接置处理器于空转
仅保护宿主内核还不够:如果客户机(guest)能把处理器直接置于空转状态,guest 控制的 CALL/返回目标就可能成为 RAP 中的“脏数据”。因此 KVM 虚拟化层还需拦截客户机的 HLT 与 MWAIT 指令,避免 guest 绕过宿主内核的 RSB 填充路径直接触发 1T/2T 切换。
以 SVM(AMD/ Hygon 的硬件虚拟化扩展)为例,在 arch/x86/kvm/svm/svm.c 中,KVM 初始化 VMCB 拦截位时:
- 仅当
!kvm_mwait_in_guest()时才设置INTERCEPT_MONITOR与INTERCEPT_MWAIT; - 仅当
!kvm_hlt_in_guest()时才设置INTERCEPT_IDLE_HLT/INTERCEPT_HLT。
即:默认情况下这些指令均被拦截;只有当 VMM 通过 KVM_CAP_X86_DISABLE_EXITS 显式“取消退出”后,拦截位才会被清除。kvm_hlt_in_guest()/kvm_mwait_in_guest() 等辅助函数通过检查 kvm->arch.disabled_exits 位掩码(对应 KVM_X86_DISABLE_EXITS_HLT、KVM_X86_DISABLE_EXITS_MWAIT、KVM_X86_DISABLE_EXITS_CSTATE)判定该 VM 是否允许在 guest 内直接执行这些指令,见 arch/x86/kvm/x86.h。
缓解控制与配置实操
内核命令行:沿用既有 Spectre v2 缓解
Cross-Thread RSB 的内核侧防护不引入新开关,直接使用现有 Spectre v2 缓解即可:保持默认的 retpoline/Safe RET 与上下文切换 RSB 填充不被关闭(不要使用 spectre_v2=off、mitigations=off 之类的破坏性开关)。具体可用取值与影响可查阅 Documentation/admin-guide/hw-vuln/spectre.rst 及 Documentation/admin-guide/hw-vuln/rsb.rst。
KVM 缓解开关:kvm.mitigate_smt_rsb
默认行为如下:
- 默认情况下,KVM 本身就通过拦截 guest 的 C0 退出尝试来缓解该问题(即拦截 HLT/MWAIT);
- 但 VMM 可以使用
KVM_CAP_X86_DISABLE_EXITScapability 请求取消这些拦截。由于实际使用该 capability 的 VMM 并不常见,针对这条“取消拦截”路径的强制缓解默认并未开启。
补充防护通过 KVM 模块的布尔参数 kvm.mitigate_smt_rsb 打开:
kvm.mitigate_smt_rsb=1
例如在 /etc/modprobe.d/ 下添加配置后重新加载 kvm 模块,或在内核命令行通过 kvm.mitigate_smt_rsb=1 传入。在源码中(arch/x86/kvm/x86.c):
/* Enable/disable SMT_RSB bug mitigation */
static bool __read_mostly mitigate_smt_rsb;
module_param(mitigate_smt_rsb, bool, 0444);
其生效逻辑在 arch/x86/kvm/x86.c 的模块初始化函数中收口:
mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
也就是说,即使显式传入 kvm.mitigate_smt_rsb=1,也只有当 CPU 实际携带 X86_BUG_SMT_RSB 漏洞标志且 SMT 可能启用时,该参数才真正生效——在不受影响或 SMT 禁用的系统上它是空操作,这是设计上的自动降级。
该参数如何起作用?见 arch/x86/kvm/x86.c 的 kvm_get_allowed_disable_exits():
static u64 kvm_get_allowed_disable_exits(void)
{
u64 r = KVM_X86_DISABLE_EXITS_PAUSE;
if (boot_cpu_has(X86_FEATURE_APERFMPERF))
r |= KVM_X86_DISABLE_EXITS_APERFMPERF;
if (!mitigate_smt_rsb) {
r |= KVM_X86_DISABLE_EXITS_HLT |
KVM_X86_DISABLE_EXITS_CSTATE;
if (kvm_can_mwait_in_guest())
r |= KVM_X86_DISABLE_EXITS_MWAIT;
}
return r;
}
含义一目了然:
- 当
mitigate_smt_rsb为 0(默认)时,VMM 通过KVM_CAP_X86_DISABLE_EXITS可请求的取消项包含HLT、CSTATE、MWAIT(后者还需 CPU 支持 MWAIT 虚拟化条件kvm_can_mwait_in_guest():具备X86_FEATURE_MWAIT、无X86_BUG_MONITOR、具备X86_FEATURE_ARAT); - 当
mitigate_smt_rsb=1时,这三项从“可取消集合”中被剔除,VMM 即使请求也无法关闭对应拦截,从而保证 guest 无法直接置处理器于空转。
该 capability 的处理在 arch/x86/kvm/x86.c:内核首先校验 cap->args[0] 不超过 kvm_get_allowed_disable_exits() 允许的位,随后通过 kvm_disable_exits(kvm, cap->args[0]) 落掩码。特别地,在处理器受影响(X86_BUG_SMT_RSB)、SMT 可能存在、且未开启 mitigate_smt_rsb 的情况下,如果 VMM 请求了超出 PAUSE/APERFMPERF 的取消项,KVM 会通过 pr_warn_once() 打印一条警示(SMT_RSB_MSG):
"This processor is affected by the Cross-Thread Return Predictions vulnerability. KVM_CAP_X86_DISABLE_EXITS should only be used with SMT disabled or trusted guests."
这条警告的含义是:在受影响的处理器上,只有已关闭 SMT 或完全信任 guest 时才应取消对 HLT/MWAIT/CSTATE 的拦截。若在宿主日志中看到该消息,说明当前配置正在放宽对该漏洞的保护。
推荐配置组合
综合文档与源码,面向受影响平台的加固建议如下:
- 保持默认 Spectre v2 缓解开启,确保上下文切换路径的 RSB 填充生效;
- 若 CPU 属于 AMD Family 17h / Hygon Family 18h 且启用了 SMT,建议加载 kvm 模块时传入
kvm.mitigate_smt_rsb=1,从“允许集合”中排除 HLT/CSTATE/MWAIT 取消项; - 对于确需使用
KVM_CAP_X86_DISABLE_EXITS取消这些退出的高性能场景,先评估自身是否满足“SMT 已关闭”或“guest 可信”的前提; - 如无强需求,直接关闭 SMT 也是消除该 SMT 侧信道的终极手段(内核对该 CPU bug 的强制缓解判定同样依赖
cpu_smt_possible())。
状态查询与延伸阅读
系统整体漏洞缓解状态可通过 sysfs 查看。内核在 /sys/devices/system/cpu/vulnerabilities/ 下按漏洞公开状态文件(输出形如 "Not affected" / "Vulnerable" / "Mitigation: ..."),其中 spectre_v2 文件反映了含 RSB 填充在内的 Spectre v2 缓解状态,接口说明见 Documentation/ABI/testing/sysfs-devices-system-cpu。完整的 CPU 漏洞/缓解状态文件清单与通用读取方式见 Documentation/admin-guide/hw-vuln/index.rst。
相关主题的进一步阅读:
- 本文源头文档:Documentation/admin-guide/hw-vuln/cross-thread-rsb.rst
- RSB/返回栈缓冲填充缓解:Documentation/admin-guide/hw-vuln/rsb.rst
- Spectre v2 缓解总览与命令行参数:Documentation/admin-guide/hw-vuln/spectre.rst
- 同代 SMT 返回预测问题(Retbleed):Documentation/admin-guide/hw-vuln/retbleed.rst(注:同目录 srso.rst 亦记录了关联的 AMD SMT 返回预测缓解,可作为交叉参考)
- 漏洞判定与黑名单实现:arch/x86/kernel/cpu/common.c
- KVM 侧开关与 capability 处理:arch/x86/kvm/x86.c、x86.h、svm.c
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00