Linux 内核 RSB 相关缓解机制全解:SpectreRSB、RETBleed/SRSO 与 RSB 下溢防护的纵深实现
自 2018 年 Spectre 系列漏洞爆发以来,围绕 Return Stack Buffer(RSB,AMD 体系下也称 Return Address Stack,RAS / Return Address Predictor,RAP)陆续出现了大量 CVE。这些漏洞的成因与缓解方案散落在各家 CPU 厂商的微架构文档中,很难快速形成全局认知。本文以内核文档 Documentation/admin-guide/hw-vuln/rsb.rst 为骨架,结合 Linux 内核 x86 平台的实际实现代码,系统梳理两类 RSB 攻击(RSB 投毒与 RSB 下溢)分别覆盖哪些攻击向量、内核在上下文切换与 VMEXIT 边界上分别采取了哪些缓解,以及这些缓解在源码中的确切落点。读完本文,你将能够看懂 /sys/devices/system/cpu/vulnerabilities/spectre_v2 输出中 RSB filling 等字样的含义,理解 spectre_v2=、spectre_v2_user=、spec_rstack_overflow= 等内核参数与 RSB 缓解之间的关系,并能在内核源码中独立定位每一条缓解路径。
从一份"超长注释"说起:rsb.rst 的定位
rsb.rst 在内核文档中的定位非常特殊:它的正文开头就有一个警告——"请保持本文档持续更新,否则你将被拉去更新它,并被改写成 bugs.c 里一条超长的注释"。这透露了它的真实角色:这是挂在 arch/x86/kernel/cpu/bugs.c 缓解选择逻辑之上的"规范性注释"。事实上,bugs.c 中的 spectre_v2_select_rsb_mitigation() 函数在注释里明确要求:任何人改动 RSB 相关缓解代码前,必须先精读本文档并同步更新(见 arch/x86/kernel/cpu/bugs.c#L1990-L1995)。
文档刻意不做两件事:不讲解 RSB 硬件机制本身,也不讲解 exploit 的具体构造。它的目标读者是"下一次 CVE 到来时需要快速回忆当前内核在做什么、为什么这么做的内核开发者"。因此它把问题收敛为两条主线:
- RSB 投毒(RSB poisoning):同时影响 Intel 与 AMD;
- RSB 下溢(RSB underflow):目前仅影响 Intel。
而每条攻击线都必须逐个"攻击向量 × 微架构"单独评估。所谓攻击向量,正是文档反复出现的三个域间切换边界:
- 上下文切换 user→user;
- 上下文切换 user→kernel;
- VMEXIT guest→host。
下面先厘清攻击与缓解的基本面,再逐一深入各边界的具体防护。
攻击面总览:为什么域间切换是核心战场
RSB 是硬件用来预测 RET 目标的小型栈结构,正常时保存着与调用栈对称的返回地址。当执行流出现不成对的 CALL/RET(例如上下文切换、VMEXIT 之后)时,RSB 中就可能残留着低特权域(guest、用户态)塞入的地址。高特权域(内核、host)随后执行 RET 时,CPU 若对残留的投毒条目进行推测执行,攻击者就获得了瞬态执行(transient execution)窗口,即 Spectre 类攻击。
bugs.c 顶部那段给维护者看的"简化版速记"把整个缓解策略压缩为三条(见 arch/x86/kernel/cpu/bugs.c#L1997-L2008):
- user→user:由上下文切换时按需执行的 IBPB(
cond_mitigation → write_ibpb())有条件地缓解; - user→kernel 与 guest→host:由 eIBRS 或 RSB 填充(RSB filling)缓解;
- 视内核配置不同,还可能叠加其它替代方案:entry/VMEXIT 上的 IBPB、call depth tracking(调用深度跟踪)、return thunks 等。
上述三类"域间"攻击之所以能被挡下来,很大程度上依赖一条硬件事实:高特权域执行受保护的关键代码前,要么清除/覆盖了推测源,要么通过特权隔离(如 SMEP)让投毒地址无法被取指。理解了这张总图,再来看两类攻击的具体推演。
攻击类别一:RSB 投毒(RSB poisoning)
RSB 投毒是 SpectreRSB 的核心技术:攻击者让受害者的 RET 指令推测到攻击者控制的地址。它出现的典型前提是上下文切换或 VMEXIT 后存在不成对的 CALL/RET,使残余条目恰好能被受害域"消费"。
SpectreRSB:通用投毒与三种缓解路径
文档给出的通解是:在不可信域 → 可信域转换时,用一段 RSB 填充序列把投毒条目冲刷掉。但文档同时提醒,填充是有性能开销的,应当尽可能避免。这段填充序列的实现细节见后文"RSB 填充序列的实现",其核心是把每一个 RSB 槽位填成一个"捕获推测执行"的陷阱——通常是一条会陷入自旋的无害循环。
在上下文切换的 user→user 攻击上,关键是让 RSB 的清除与 IBPB 的写入保持同步,即"每次写入 IBPB 时必须同时填充或清空 RSB"。这又分 CPU 厂商讨论:
- AMD:在 Zen 4 及更新的处理器上,IBPB(若启用 SBPB,即以不冲刷分支类型预测为代价的 IBPB 变体,仅 AMD 存在)会顺带清空 RSB,这一能力由 CPUID leaf 8000_0008h 中的
IBPB_RET位体现。而 Zen 4 之前的处理器,IBPB 不触碰 RSB 的返回目标预测,因此必须在 IBPB 之外无条件再做一次 RSB 填充。内核用X86_BUG_IBPB_NO_RET这一 bug 标志记录"IBPB 不清返回目标预测"的处理器。 - Intel:Intel 文档断言 IBPB 总会清空 RSB——"IBPB 命令执行前运行的软件无法控制该命令之后在同一逻辑处理器上执行的间接分支的预测目标;此处的间接分支包括近返回指令,其预测目标可能来自 RSB"。
在源码层面,AMD 的这条分水岭在启动阶段就被固化成了 CPU bug 位。在 arch/x86/kernel/cpu/common.c#L1598-L1599 中:
if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
即:只要 CPU 支持 AMD IBPB、却不带 AMD_IBPB_RET(没有 leaf 8000_0008h 的 IBPB_RET 位),就被判定为 IBPB_NO_RET。该 bug 位定义于 arch/x86/include/asm/cpufeatures.h#L582。随后,在 IBPB 的执行路径 write_ibpb() 中,只有在 IBPB_NO_RET 存在时才会追加 RSB 填充(见 arch/x86/entry/entry.S#L22-L33):
SYM_FUNC_START(write_ibpb)
ANNOTATE_NOENDBR
movl $MSR_IA32_PRED_CMD, %ecx
movl _ASM_RIP(x86_pred_cmd), %eax
xorl %edx, %edx
wrmsr
/* Make sure IBPB clears return stack preductions too. */
FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET
RET
SYM_FUNC_END(write_ibpb)
这段汇编清晰对应文档描述:Intel 上 IBPB 本身已清 RSB,无需填充;AMD Zen 4+(带 IBPB_RET)同样无需填充;只有 X86_BUG_IBPB_NO_RET 的老 AMD 需要额外 FILL_RETURN_BUFFER。
user→kernel 投毒:SMEP 才是第一道墙
文档强调,上下文切换的 user→kernel 投毒攻击主要由 SMEP(Supervisor Mode Execution Prevention)挡住:用户态只能把用户态地址写进 RSB,即使是非规范地址,也会因为 TASK_SIZE_MAX 在用户态规范地址空间末尾保留的页间隙而无法写入。当内核在取指时触发 SMEP #PF,就不可能推测执行用户空间。
- AMD 文档将这种组合称为 RAP Protection:"被预测为
ret的分支,其预测目标来自 Return Address Predictor(RAP)。AMD 建议软件使用 RAP stuffing 序列(缓解方案 V2-3)和/或 SMEP,确保 RAP 中的地址对推测执行是安全的。" - Intel 则指出:在支持 enhanced IBRS 的处理器上,仅靠 RSB 覆写序列可能不足以阻止近返回使用低特权预测模式创建的 RSB 条目;软件应启用 SMEP(针对 user→supervisor 转换),并在 VM exit 期间保持
IA32_SPEC_CTRL.IBRS置位。
VMEXIT guest→host 投毒:eIBRS 与 PBRSB
guest→host 攻击的基准缓解是 eIBRS(enhanced IBRS),必要时叠加 PBRSB 缓解:
- AMD(Automatic IBRS):"启用 Automatic IBRS 时,用于返回地址预测的内部返回地址栈会在 VMEXIT 时被清空。"
- Intel:在支持 enhanced IBRS 的处理器上,只要 IBRS 在 VM exit 后置位,即使 VM exit 发生时 IBRS 未置位,处理器也会保证 guest 行为无法控制 RSB。
但文档特别点出:部分 Intel CPU 存在 PBRSB(Post-barrier Return Stack Buffer Predictions)问题,即 guest 发出的最后一个 CALL 可能被用来预测 VMEXIT 后第一个不成对的 RET。这类 CPU 需要在 eIBRS 之外额外增加 PBRSB 缓解。内核的应对是引入 X86_BUG_EIBRS_PBRSB(见 arch/x86/include/asm/cpufeatures.h#L572)与轻量级能力位 X86_FEATURE_RSB_VMEXIT_LITE。在 spectre_v2_select_rsb_mitigation() 中(见 arch/x86/kernel/cpu/bugs.c#L2014-L2021),当选择 eIBRS 系缓解且 CPU 命中 EIBRS_PBRSB 时,内核只设置 RSB_VMEXIT_LITE——对应在 VMEXIT 路径"退役单个 CALL"而不是全量填充 RSB(X86_FEATURE_RSB_VMEXIT_LITE 定义于 arch/x86/include/asm/cpufeatures.h#L305)。
这条"单个 CALL 即可"的思路体现在宏 __FILL_ONE_RETURN 上(见 arch/x86/include/asm/nospec-branch.h#L167-L179):为了缓解 PBRSB 推测,必须强制一条 CALL 先于任何 RET 退役;在 PBRSB 易感 CPU 上,此点之前执行 RET 是不安全的。VMX 的 VMEXIT 路径正是这样调用填充宏的(见 arch/x86/kvm/vmx/vmenter.S#L171-L172):
FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT,\
X86_FEATURE_RSB_VMEXIT_LITE
这里 ALTERNATIVE_2 式的双特征选择意味着:完整 RSB 填充(RSB_VMEXIT)与轻量单 CALL 方案(RSB_VMEXIT_LITE)由运行时 CPU 特征自动二选一。而 AMD SVM 侧则直接按 RSB_VMEXIT 做全量填充,见 arch/x86/kvm/svm/vmenter.S#L136 与 arch/x86/kvm/svm/vmenter.S#L252。
AMD 专属投毒面:RETBleed / SRSO / Branch Type Confusion
文档单独列出了 AMD 上能"制造"投毒 RSB 条目的三类攻击:
- AMD RETBleed(亦称 Branch Type Confusion):间接分支预测器与返回预测器之间的类型混淆;
- Speculative Return Stack Overflow(SRSO,Inception):用深层调用让 RSB 溢出,从而污染预测目标。
面对这些变体,内核的保护思路非常直接:把内核里的每一条 RET 都替换成跳转到唯一一条安全的 RET(safe RET)——即引入 return thunk。当代码中不再有"裸 RET"、所有返回都汇聚到一个受控的 safe RET 序列时,攻击者难以找到可利用的 RET 指令来喂投毒条目。
该机制在源码中的落点是 arch/x86/lib/retpoline.S(srso_return_thunk / srso_alias_return_thunk / srso_safe_ret 系列),选择逻辑位于 arch/x86/kernel/cpu/bugs.c#L2938 起的 srso_select_mitigation():内核会根据 CPU 是否命中 X86_BUG_SRSO(由 arch/x86/kernel/cpu/common.c#L1570-L1573 依据漏洞黑名单设置)、是否支持 SRSO_NO、微码是否具备 SRSO_MSR_FIX 等条件,选择 safe RET、microcode、IBPB、IBPB-only-on-VMEXIT 或 BP_SPEC_REDUCE 等档位,最终通过 set_return_thunk() 把内核返回路径切到对应 thunk(见 arch/x86/kernel/cpu/bugs.c#L3057-L3060)。AMD Zen 1–4 的缓解档位、safe-ret 与 alias 方案的取舍可进一步参考同目录文档 Documentation/admin-guide/hw-vuln/srso.rst。
此外,CALL/NOSPEC 类宏与 CALL_UNTRAIN_RET(见 arch/x86/include/asm/nospec-branch.h#L305-L309)负责在需要"训练(untrain)"的位置直接内联调用 entry_untrain_ret 或 srso_alias_untrain_ret,其中 X86_FEATURE_UNRET / X86_FEATURE_SRSO_ALIAS 分别对应 UNRET(AMD RETBleed)与 SRSO alias 方案。
攻击类别二:RSB 下溢(RSB underflow,仅 Intel)
第二类攻击的前提是 RSB 已空:当不成对的 RET 过多、或从过深的调用栈返回时,RSB 出现空槽,RET 预测会"回退"到 Branch Target Buffer(BTB)。若攻击者能制造 BTB 碰撞,RET 就可能推测跳转到攻击者控制的地址。文档提示两个关键推论:
- RSB 填充并不能完全消除这类攻击——只要不成对的 RET 足够多,RSB 仍可能被掏空并回退到被投毒的 BTB 条目;
- 所以缓解必须同时治理"BTB 这个回退源",这正是 IBPB 与 eIBRS/IBRS 被反复启用的原因。
RSBA(RSB Alternate,即 Intel 版 RETBleed / RSB Underflow)
部分 Skylake 代 Intel CPU 受 Intel 版 RETBleed(Return Stack Buffer Underflow,CVE-2022-29901 / CVE-2022-28693 系列)影响。针对不同边界:
- user→user(上下文切换):依靠有条件的 IBPB 缓解。IBPB 被定义为"间接分支预测屏障"——在同一逻辑处理器上,屏障之前执行的软件无法控制屏障之后执行的间接分支的预测目标。由于 user→user 下溢攻击本质上借助了 BTB 中的碰撞条目,IBPB 相当于把 BTB 清空。这就是
spectre_v2_user系列选项要解决的问题(详见下文参数一节)。 - user→kernel 与 guest→host(上下文切换与 VMEXIT):由 IBRS / eIBRS 缓解。Intel 文档明确:"启用 IBRS(含 enhanced IBRS)即可缓解研究人员演示的 RSBU 攻击。Intel 建议优先使用 enhanced IBRS;凡是枚举了 RRSBA 而未枚举 RRSBA_DIS_S 的处理器都应启用 enhanced IBRS。"
但文档同时给出重要警告:eIBRS 与 IBRS 无法缓解域内(intra-mode)攻击——如果攻击者与受害者同处一个域(如都来自内核态视角的预测域),IBRS 的域隔离假设就不成立。这类域内问题与下文的 RRSBA 一样,靠"在内核入口清除 BHB(Branch History Buffer)"来解决。
作为经典 IBRS 之外的另一条路,call depth tracking(调用深度跟踪)配合 retpoline,可以跟踪内核返回并在 RSB 接近空时主动填充它。这套机制在 arch/x86/include/asm/nospec-branch.h#L19-L56 有详细说明与实现(含 RSB_RET_STUFF_LOOPS、CREDIT_CALL_DEPTH、INCREMENT_CALL_DEPTH 等宏),其思路正是针对 Skylake 代 CPU 的 RSB 下溢:通过记账式跟踪调用深度,避免 RET 时 RSB 恰好见底。
RRSBA(Restricted RSB Alternate)与 BHI 的交叉
部分较新的 Intel CPU 具有 Restricted RSB Alternate(RRSBA) 行为:与 RSBA 类似在 RSB 空时回退到 BTB,唯一区别是——启用 eIBRS 时,回退预测目标被限制在当前预测域的间接分支预测条目内。也就是说 eIBRS 场景下 RRSBA 把跨域风险关进了笼子,域内风险仍在。
由此产生两条派生规则:
- 当一台带 RRSBA 的 CPU 同时易受 Branch History Injection(BHI) 攻击时,RSB 下溢可被用作域内 BTI(分支目标注入)攻击的载体——缓解手段是在内核入口清除 BHB。
- 如果内核用 retpoline 而非 eIBRS,就必须主动关闭 RRSBA 行为(Intel 文档:凡软件以 retpoline 作为 BHI/域内 BTI 缓解、且 CPU 同时枚举 RRSBA 与 RRSBA_DIS 控制位的,应禁用该行为)。
内核在 arch/x86/kernel/cpu/bugs.c#L1969-L1986 的 spec_ctrl_disable_kernel_rrsba() 中落地了这条规则:仅当 ARCH_CAP_RRSBA 置位且 CPU 具备 X86_FEATURE_RRSBA_CTRL 时,才向 MSR_IA32_SPEC_CTRL 写入 SPEC_CTRL_RRSBA_DIS_S,从而禁用内核使用非 RSB 的 RET 预测源。该函数被调用在两处(见 arch/x86/kernel/cpu/bugs.c#L2111-L2114 与 arch/x86/kernel/cpu/bugs.c#L2314-L2321):一处面向"retpoline 对抗 BHI"的配置,另一处面向内核同时使用 retpoline 与调用深度跟踪的配置。
RSB 填充序列的实现:从宏到运行时修补
文档反复提到的 "RSB filling / stuffing sequence",其实现集中在 arch/x86/include/asm/nospec-branch.h。逐层拆解如下:
- 槽位填充原语
__FILL_RETURN_SLOT(nospec-branch.h#L129-L133):执行一次call 772f; int3; 772:,把返回地址压入 RSB。若该地址被推测性使用,int3/紧随其后的内容会捕获推测执行,不会真正跳到攻击者地址。 - 全量填充
__FILL_RETURN_BUFFER(reg, nr)(nospec-branch.h#L142-L165):64 位下采用"每轮两次 call + 末尾lfence"的循环结构。注释说明这是 Google 实测后的最优形态——两个各自携带推测陷阱的 call 放在一个循环里,lfence则为jnz的预测错误提供屏障。 - 填充规模常量
RSB_CLEAR_LOOPS(nospec-branch.h#L124):当前固定为 32 次。这正是文档中DANGER/FIXME警告所指的问题:部分 CPU 型号的 RSB 条目数超过 32,届时必须提高循环次数——文档明确要求未来补充各型号 RSB 深度的详细数据后再调整。 - 统一封装
FILL_RETURN_BUFFER宏(nospec-branch.h#L289-L295):用ALTERNATIVE_2把整段填充逻辑做成运行时补丁,可按 CPU 特征在"跳过""全量填充""单 CALL 轻量填充"之间切换,且该宏同时服务于 C 内联汇编与.S文件。
这条宏的实际调用点正是前文各边界的执行路径:
- 上下文切换:
__switch_to_asm()中,切换栈后立即执行FILL_RETURN_BUFFER %r12, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW(见 arch/x86/entry/entry_64.S#L199-L206,注释说明:从较浅栈切到较深栈时 RSB 可能下溢或残留用户态地址,因此要覆写 RSB)。32 位对应 arch/x86/entry/entry_32.S#L704。 - VMEXIT:VMX 侧见上文 arch/x86/kvm/vmx/vmenter.S#L171-L172,SVM 侧见 arch/x86/kvm/svm/vmenter.S#L136。
- IBPB 副作用补偿:
write_ibpb()内按X86_BUG_IBPB_NO_RET条件填充(见 arch/x86/entry/entry.S#L30)。
而各"该不该填充"的能力位集中在 arch/x86/include/asm/cpufeatures.h:X86_FEATURE_RSB_VMEXIT(第 732+13 位,VMEXIT 时填充 RSB)、X86_FEATURE_RSB_CTXSW(732+19,上下文切换时填充)、X86_FEATURE_RSB_VMEXIT_LITE(1132+17)、X86_FEATURE_RRSBA_CTRL(1132+11)。它们由 spectre_v2_select_rsb_mitigation()(arch/x86/kernel/cpu/bugs.c#L1988)根据最终选定的 Spectre v2 缓解档位统一置位:
- 档位为 eIBRS 系(
SPECTRE_V2_EIBRS/_EIBRS_LFENCE/_EIBRS_RETPOLINE)且命中EIBRS_PBRSB→ 仅设RSB_VMEXIT_LITE; - 档位为
RETPOLINE/LFENCE/IBRS→ 设RSB_CTXSW+RSB_VMEXIT(完整填充两条路径都开),并打印 "SpectreRSB: Filling RSB on context switch and VMEXIT"。
这也解释了为什么 /sys/devices/system/cpu/vulnerabilities/spectre_v2 里会出现 ; RSB filling 这样的后缀(对应 X86_FEATURE_RSB_CTXSW,见 arch/x86/kernel/cpu/bugs.c#L3557),以及 Mitigation: Retpolines, Stuffing RSB 之类的档位描述(arch/x86/kernel/cpu/bugs.c#L1399)。运行时可通过 srbds/srso 等 vuln 属性观察当前 SRSO 缓解状态(srso_show_state(),见 arch/x86/kernel/cpu/bugs.c#L3587)。
相关内核参数与运行态观察
RSB 缓解并不是一个独立开关,而是内嵌在 Spectre v2 的整体缓解框架中,由如下三个 EARLY 参数联动控制(完整语义见 Documentation/admin-guide/kernel-parameters.txt):
spectre_v2=(kernel-parameters.txt#L7134)
控制内核态对间接分支推测(Spectre v2)的缓解,取值主要有:
| 取值 | 含义 | 对 RSB 缓解的典型影响 |
|---|---|---|
on |
无条件启用,隐含 spectre_v2_user=on |
运行时按 CPU/微码/配置选档,可能触发 RSB 填充 |
off |
无条件禁用,同时关闭用户态防护 | 不填充 RSB、不启用相关档位 |
auto |
默认值,按 CPU 型号自动检测漏洞 | 等价于不写该参数 |
retpoline |
以 retpoline 替换间接分支 | 档位属 RETPOLINE 系,会开 RSB_CTXSW+RSB_VMEXIT 全量填充;配合 BHI/RRSBA 场景还会置 RRSBA_DIS_S |
eibrs / eibrs,retpoline / eibrs,lfence |
Enhanced/Auto IBRS 及组合 | 档位属 eIBRS 系,通常只按 EIBRS_PBRSB 决定是否补 PBRSB 轻量序列 |
ibrs |
仅用经典 IBRS 保护内核 | 同样触发 RSB 填充路径 |
若 CPU 易感 SpectreRSB 而内核又未编译 retpoline,则会打印 "RSB stuff mitigation not supported, using default" 之类的提示(见 arch/x86/kernel/cpu/bugs.c#L1463)。
spectre_v2_user=(kernel-parameters.txt#L7174)
专门控制用户态任务之间的 Spectre v2 缓解,正是文档中 "user→user" 与"条件 IBPB(conditional IBPB)"的开关所在。取值包括:
on/off:无条件开/关(由spectre_v2=on/off强制);prctl:默认策略,允许进程通过prctl按线程开启,控制状态随fork继承;prctl,ibpb:类似prctl,但 IBPB 在切换到不同用户态进程时始终下发,只把 STIBP 交由线程自行控制;seccomp/seccomp,ibpb:与上两组对应,但所有 seccomp 线程默认开启(除非显式 opt-out);auto:内核按 CPU 能力与漏洞状态选择。
文档中的 cond_ibpb(conditional IBPB)即指"是否写 IBPB 取决于 prev/next 任务是否受 Spectre 保护、是否按任务或全局启用",通常需要逐任务 opt-in 或系统级开启——对应的正是 prctl 与 seccomp 家族选项。结合前文可知,在带 X86_BUG_IBPB_NO_RET 的 AMD 上,这些选项触发 IBPB 的同时还会顺带执行 RSB 填充,而 Intel 上 IBPB 本身即清空 RSB。
spec_rstack_overflow=(kernel-parameters.txt#L7215)
AMD Zen CPU 上控制 RAS 溢出(SRSO,即 AMD 侧制造投毒 RSB 条目的攻击)的缓解:
off:禁用;microcode:仅用微码缓解;safe-ret:默认值,纯软件 safe RET 缓解;ibpb:内核入口下发 IBPB;ibpb-vmexit:仅在 VMEXIT 下发 IBPB(面向云场景的专用缓解)。
这些选项的解析在 arch/x86/kernel/cpu/bugs.c#L2914-L2934,最终会反映到 srso 相关的 sysfs 状态中。
观察运行态
所有缓解档位均可从 sysfs 读取(路径 .../cpu/bugs.c 中 cpu_show_* 系列的实现对应 /sys/devices/system/cpu/vulnerabilities/*):
cat /sys/devices/system/cpu/vulnerabilities/spectre_v2
cat /sys/devices/system/cpu/vulnerabilities/srso
若看到输出中含 ; RSB filling、PBRSB-eIBRS: SW sequence、Mitigation: Retpolines, Stuffing RSB 等字样,即可据此推断当前 CPU 上 RSB 投毒/下溢缓解以何种形态生效。
小结:一张 RSB 缓解对照表
把文档的结论压缩成一张速查表,便于对照源码与运行态:
| 攻击向量 | 威胁类别 | 微架构 | 主要缓解 | 源码落点 |
|---|---|---|---|---|
| user→user(ctx switch) | 投毒 | AMD Zen 4+ | IBPB/SBPB 自带清 RSB(IBPB_RET) | arch/x86/kernel/cpu/common.c#L1598、write_ibpb() |
| user→user(ctx switch) | 投毒 | AMD Zen<4 | IBPB + 必须 RSB 填充(X86_BUG_IBPB_NO_RET) |
arch/x86/entry/entry.S#L30 |
| user→user(ctx switch) | 投毒 | Intel | IBPB 自身清 RSB | write_ibpb() |
| user→user(ctx switch) | 下溢(RSBA) | Intel Skylake 代 | 条件 IBPB 清 BTB(spectre_v2_user=) |
Documentation/admin-guide/kernel-parameters.txt#L7174 |
| user→kernel | 投毒 | Intel/AMD | SMEP(+RAP Protection / eIBRS) | 架构特性 |
| guest→host(VMEXIT) | 投毒 | AMD | Automatic IBRS 在 VMEXIT 清 RSB | arch/x86/kvm/svm/vmenter.S |
| guest→host(VMEXIT) | 投毒 | Intel | eIBRS +(EIBRS_PBRSB 时)单 CALL 轻量序列 | arch/x86/kvm/vmx/vmenter.S#L171、__FILL_ONE_RETURN |
| user→kernel / guest→host | 下溢(RSBU) | Intel | IBRS/eIBRS;或 call depth tracking + retpoline | RSB_RET_STUFF_LOOPS、call depth 宏 |
| 域内(intra-mode) | 下溢(RRSBA)+BHI | Intel 新代 | 内核入口清 BHB;retpoline 时置 RRSBA_DIS_S |
spec_ctrl_disable_kernel_rrsba() |
| 内核自身返回 | 投毒(RETBleed/SRSO/BTC) | AMD | 全量 safe RET / return thunk(spec_rstack_overflow=) |
arch/x86/kernel/cpu/bugs.c#L2938、arch/x86/lib/retpoline.S |
对内核开发者而言,rsb.rst 的真正价值在于它把散落各处的硬件通告收敛成"变更前必读"的单一事实源——正如 spectre_v2_select_rsb_mitigation() 中的注释所要求的:改动任何 RSB 相关代码前先更新这份文档,而文档与 arch/x86/include/asm/nospec-branch.h、arch/x86/kernel/cpu/bugs.c 互为印证,构成理解这条复杂缓解链路的完整闭环。后续若出现新的 RSB 相关 CVE,判断"属于投毒还是下溢、发生在哪个域间边界、当前代码走了哪条填充/屏障路径",就是定位与评估缓解是否完备的第一步。
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 StartedRust0627
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