ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux 内核 GDS(Gather Data Sampling)漏洞缓解指南:原理、微码 MSR 控制与内核命令行开关

Linux 内核 GDS(Gather Data Sampling)漏洞缓解指南:原理、微码 MSR 控制与内核命令行开关 Linux 内核 GDSGather Data Sampling漏洞缓解指南原理、微码 MSR 控制与内核命令行开关【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linuxGather Data SamplingGDS是 Linux 内核中登记的一项 x86 硬件侧信道漏洞它允许非特权攻击者通过推测执行间接访问此前存放在向量寄存器vector registers中的陈旧数据。本文以内核文档 Documentation/admin-guide/hw-vuln/gather_data_sampling.rst 为骨架结合 x86 平台漏洞缓解源码arch/x86/kernel/cpu/bugs.c、arch/x86/kernel/cpu/common.c 等与 MSR 定义系统讲解 GDS 的成因、攻击面、微码缓解机制、内核命令行控制方式以及如何通过 sysfs 与 dmesg 确认当前系统的缓解状态。GDS 是什么gather 指令触发的矢量寄存器数据泄漏GDS 是一类纯采样型sampling-based的瞬态执行攻击。攻击原理在于gather收集指令的异常路径当一条 gather 指令从内存加载多个数据元素并合并写入目标向量寄存器时如果这条指令只是被瞬态执行transiently executed并遇到故障fault此时来自架构可见architectural或内部向量寄存器的陈旧数据就可能被瞬态转发到目标向量寄存器中。攻击者随后利用典型的侧信道手段例如 cache timing推断这些陈旧数据的内容。该漏洞的关键特点包括攻击者必须主动使用 gather 指令才能触发并采样数据受害者无需任何特殊操作只要曾经使用过向量寄存器即可能成为数据源受害者甚至不需要使用 gather 指令也会处于脆弱状态由于相关内部缓冲在Hyper-Thread 之间共享因此存在跨 Hyper-ThreadSMT攻击的可能。在内核源码中GDS 作为一类独立的 CPU 漏洞bug被登记例如 arch/x86/include/asm/cpufeatures.h 中的#define X86_BUG_GDS X86_BUG(30) /* gds CPU is affected by Gather Data Sampling */X86_BUG_*位正是内核漏洞检测与 sysfs 状态导出机制的“主键”后续介绍的 select/apply mitigation 流程都围绕它展开。攻击场景跨越几乎所有权限边界从文档给出的威胁模型看在没有缓解措施的情况下GDS 理论上可以跨越几乎所有的权限边界推断陈旧数据具体包括攻击方向能推断的数据非 Enclave → SGX EnclaveEnclave 内部数据用户态 → 内核态内核数据Guest → Host宿主机数据Guest → 其他 Guest其他虚拟机数据用户 → 其他用户其他进程/用户的数据正是由于攻击面横跨内核态、SGX 与虚拟化边界文档特别强调必须确保缓解措施在低特权上下文中保持启用例如在 guest 内运行时、以及在 SGX Enclave 之外执行时。具体到虚拟化场景硬件本身会为SGX强制实施缓解同理VMM虚拟机监控器应当保证 guest 无法关闭 GDS 缓解。文档明确警告如果宿主机配置出错允许 guest 关闭 GDS 缓解那么 guest 理论上可以“先关闭缓解 → 发起攻击 → 再恢复缓解”在几乎不留痕迹的情况下完成越权数据窃取。缓解机制一微码中的专用 MSR 位GDS 的主要缓解路径在**微码microcode**层面完成。更新的微码在现有架构 MSR 中新增并定义了如下几个位MSR 位读写属性含义IA32_ARCH_CAPABILITIES[GDS_CTRL]R/O枚举 CPU 是否易受 GDS 影响且具备缓解控制能力IA32_ARCH_CAPABILITIES[GDS_NO]R/O表示处理器不受GDS 影响IA32_MCU_OPT_CTRL[GDS_MITG_DIS]R/W关闭GDS 缓解默认值为 0即缓解默认开启IA32_MCU_OPT_CTRL[GDS_MITG_LOCK]R/W将GDS_MITG_DIS锁定为 0此后对该位的写操作被忽略且一旦置位便无法清除这些位的定义可以在内核头文件中找到对应实现。例如 arch/x86/include/asm/msr-index.h#define ARCH_CAP_GDS_CTRL BIT(25) /* CPU is vulnerable to Gather Data Sampling (GDS) * and has controls for mitigation. */ #define ARCH_CAP_GDS_NO BIT(26) /* CPU is not vulnerable to Gather Data Sampling (GDS). */ #define MSR_IA32_MCU_OPT_CTRL 0x00000123 #define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */ #define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */其中GDS_MITG_LOCKED正是文档中IA32_MCU_OPT_CTRL[GDS_MITG_LOCK]的软件对应物——内核通过读回该位来判断微码缓解是否已被硬件级锁定。缓解机制二无微码场景下降级为禁用 AVX对于尚未更新微码、因而缺失硬件缓解能力的受影响系统GDS 还可以通过禁用 AVX的方式缓解。具体做法是往内核命令行传入以下任一参数gather_data_samplingforceclearcpuidavx这两种方式的实质都是关闭 XSAVE 的 YMM 支持从而阻止内核/用户态继续使用 AVX进而无法使用以 YMM 为操作数、涉及 gather 语义的指令路径。文档针对该降级路径给出了一个重要的兼容性警告即便禁用了 YMM 支持处理器仍然会枚举enumerate出 AVX 能力。也就是说用户态程序如果没有遵循正确的 AVX 枚举流程——即同时检查 AVX和XSAVE YMM 支持两项能力——就可能在拿到 “AVX 可用” 的假象后继续使用相关指令而触发#UD未定义指令异常甚至崩溃。这要求 AVX 用户态代码必须遵守 Intel 推荐的完整枚举流程。内核命令行缓解控制off / force / 默认值GDS 缓解的运行期控制集中在内核命令行参数gather_data_sampling上其取值语义如下命令行配置效果gather_data_samplingoff显式关闭GDS 缓解mitigationsoff全局关闭缓解开关同样会使 GDS 缓解失效不指定任何参数默认保持缓解启用gather_data_samplingforce在有微码缓解的机器上强制使用微码缓解在没有更新微码的受影响机器上则禁用 AVX作为替代缓解在 arch/x86/kernel/cpu/bugs.c 中可以看到该参数的实际解析逻辑它通过early_param在内核启动早期完成注册static int __init gds_parse_cmdline(char *str) { if (!str) return -EINVAL; if (!boot_cpu_has_bug(X86_BUG_GDS)) return 0; if (!strcmp(str, off)) gds_mitigation GDS_MITIGATION_OFF; else if (!strcmp(str, force)) gds_mitigation GDS_MITIGATION_FORCE; return 0; } early_param(gather_data_sampling, gds_parse_cmdline);注意其中的细节只有当 CPU 被判定为存在X86_BUG_GDS时命令行参数才会真正生效否则直接返回——也就是说在不受影响的 CPU 上无论传入什么值都不会产生误导性的状态变更。编译期开关CONFIG_MITIGATION_GDS除运行期参数外GDS 缓解还受编译期 Kconfig 选项控制。在 arch/x86/Kconfig 中定义config MITIGATION_GDS bool Mitigate Gather Data Sampling depends on CPU_SUP_INTEL default y help Enable mitigation for Gather Data Sampling (GDS). GDS is a hardware vulnerability which allows unprivileged speculative access to data which was previously stored in vector registers. The attacker uses gather instructions to infer the stale vector register data.该选项默认开启default y且依赖CPU_SUP_INTEL。它直接决定内核的默认缓解策略——在 arch/x86/kernel/cpu/bugs.c 中static enum gds_mitigations gds_mitigation __ro_after_init IS_ENABLED(CONFIG_MITIGATION_GDS) ? GDS_MITIGATION_AUTO : GDS_MITIGATION_OFF;即编译期开启该选项时默认策略为AUTO自动按 CPU 与微码情况启用微码缓解关闭该选项时默认策略直接退化为OFF。内核侧缓解状态机从检测到写 MSR 的完整实现结合源码可以把“文档层面描述的机制”落地到一条完整的内核实现链路中。第一步漏洞检测common.cCPU 是否受影响、是否在启动早期打上X86_BUG_GDS标记由 arch/x86/kernel/cpu/common.c 完成。判定同时依赖漏洞黑名单VULNBL表、IA32_ARCH_CAPABILITIES[GDS_NO]位以及AVX 特性if (cpu_matches(cpu_vuln_blacklist, GDS) !(x86_arch_cap_msr ARCH_CAP_GDS_NO) boot_cpu_has(X86_FEATURE_AVX)) setup_force_cpu_bug(X86_BUG_GDS);从该表项同一文件内GDS位出现在 Skylake-X/L、Kaby Lake、Ice Lake、Comet Lake、Tiger Lake、Rocket Lake 等型号的 VULNBL 描述中可以看出GDS 影响的是 Intel 若干代采用 AVX 特性并支持 gather 指令的处理器。注意setup_force_cpu_bug之前的额外条件boot_cpu_has(X86_FEATURE_AVX)——文档中“通过禁用 AVX 缓解”的方案在检测侧便已埋下伏笔若 VMM 通过清除XCR0[2]禁用了 AVX2/gather则处理器不会被打上 GDS bug 标记。第二步缓解状态枚举与选择bugs.c内核内部用enum gds_mitigations表示 GDS 缓解状态见 arch/x86/kernel/cpu/bugs.cenum gds_mitigations { GDS_MITIGATION_OFF, GDS_MITIGATION_AUTO, GDS_MITIGATION_UCODE_NEEDED, GDS_MITIGATION_FORCE, GDS_MITIGATION_FULL, GDS_MITIGATION_FULL_LOCKED, GDS_MITIGATION_HYPERVISOR, }; static const char * const gds_strings[] { [GDS_MITIGATION_OFF] Vulnerable, [GDS_MITIGATION_UCODE_NEEDED] Vulnerable: No microcode, [GDS_MITIGATION_FORCE] Mitigation: AVX disabled, no microcode, [GDS_MITIGATION_FULL] Mitigation: Microcode, [GDS_MITIGATION_FULL_LOCKED] Mitigation: Microcode (locked), [GDS_MITIGATION_HYPERVISOR] Unknown: Dependent on hypervisor status, };这里的字符串表就是最终呈现在 sysfs 与 dmesg 中的状态文本。选择逻辑gds_select_mitigation的要点包括运行在虚拟化 guest中X86_FEATURE_HYPERVISOR时直接置为GDS_MITIGATION_HYPERVISOR即“取决于 hypervisor 状态”AUTO模式下若当前仍处于脆弱状态未因mitigationsoff等被关闭则进入FULL启用微码缓解否则进入OFF若 CPU 缺少ARCH_CAP_GDS_CTRL即没有更新的微码除非命令行显式指定force否则标记为UCODE_NEEDED指定了force则继续走禁用 AVX 的路径读回MSR_IA32_MCU_OPT_CTRL发现GDS_MITG_LOCKED置位时状态升级为FULL_LOCKED即使此前尝试off也会警告 “Mitigation locked. Disable failed.”。第三步落地实施update_gds_msr / apply在实施阶段update_gds_msr()arch/x86/kernel/cpu/bugs.c负责对MSR_IA32_MCU_OPT_CTRL执行实际写操作OFF状态下置位GDS_MITG_DIS即显式关闭缓解FULL/FULL_LOCKED状态下清除GDS_MITG_DIS确保缓解开启LOCKED分支的注释说明它由启动 CPUboot CPU引导而来其余应用处理器AP状态未必一致因此需要在所有 CPU 上统一写入写入后读回校验若写值被忽略例如 AP 上缓解已被锁定而 boot CPU 没有则触发WARN_ON_ONCE告警用于暴露 boot CPU 与其他 CPU 状态不一致的异常。而gds_apply_mitigation()arch/x86/kernel/cpu/bugs.c则完成两件收尾工作其一当存在ARCH_CAP_GDS_CTRL时对所有 CPU 应用微码缓解其二当处于FORCE且无微码缓解时通过setup_clear_cpu_cap(X86_FEATURE_AVX)在启动 CPU 上清除 AVX 特性位并打印Microcode update needed! Disabling AVX as mitigation.。最终统一输出当前缓解状态字符串。这两步分别由x86_vulnerability_select_mitigations/x86_vulnerability_apply_mitigations在所有X86_BUG_*的 select/apply 流程中被顺序调用同文件 arch/x86/kernel/cpu/bugs.c 与 #L3355 附近。此外在多核启动路径中每个 AP应用处理器也会执行update_gds_msr()见 arch/x86/kernel/cpu/common.c从而保证全系统所有逻辑 CPU 上的缓解状态一致。通过 sysfs 读取 GDS 状态内核通过cpu_show_common机制为每个漏洞在 sysfs 中暴露状态节点。GDS 对应的节点为/sys/devices/system/cpu/vulnerabilities/gather_data_sampling读取方式cat /sys/devices/system/cpu/vulnerabilities/gather_data_sampling该文件的取值与含义完整对应文档中的状态表并与gds_strings[]一一对应如下sysfs 输出含义Not affected处理器不受 GDS 影响Vulnerable处理器易受影响且缓解已被关闭Vulnerable: No microcode处理器易受影响但微码缺失缓解能力对应UCODE_NEEDEDMitigation: AVX disabled, no microcode处理器易受影响、微码缺失缓解已通过禁用 AVX缓解Mitigation: Microcode处理器易受影响微码缓解已生效Mitigation: Microcode (locked)缓解已生效且无法被关闭GDS_MITG_LOCKEDUnknown: Dependent on hypervisor status运行在受影响处理器的虚拟 guest 中无法得知宿主机处理器是否已缓解从源码看该节点最终由 arch/x86/kernel/cpu/bugs.c 与cpu_show_gds()#L3743-L3746提供实现本质就是sysfs_emit(buf, %s\n, gds_strings[gds_mitigation])。与此同时内核启动日志中的GDS: 前缀输出bugs.c在 GDS 段将pr_fmt重定义为GDS: 也会打印同一状态字符串可作为故障排查时与 sysfs 交叉验证的依据。在虚拟化KVM场景中的状态上报gds_strings之外KVM 侧还有一个专门针对 guest 的状态上报函数gds_ucode_mitigated()arch/x86/kernel/cpu/bugs.c通过EXPORT_SYMBOL_FOR_KVM导出给 KVM 模块使用用于判断 host 是否已通过微码完成缓解。在 arch/x86/kvm/msrs.c 中if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated()) data | ARCH_CAP_GDS_NO;即当宿主 CPU 不受 GDS 影响、或宿主已用微码缓解 GDS 时KVM 会在向 guest 呈现的IA32_ARCH_CAPABILITIES中设置GDS_NOguest 侧由此自报 “Not affected”。反过来若宿主易受影响且未用微码缓解KVM不会向 guest 暴露ARCH_CAP_GDS_NOguest 就会把状态判定为“取决于 hypervisor”从而避免 guest 在自身状态判断上产生误导。这也从实现层面印证了文档反复强调的原则VMM 必须确保 guest 无法自行关闭 GDS 缓解。默认缓解策略与运维建议文档给出的默认策略非常明确更新后的微码默认启用 GDS 缓解内核的默认行为是保持缓解处于启用状态不传任何参数时AUTO模式在有微码缓解时自动进入FULL。结合内核命令行控制运维侧建议遵循以下最佳实践保持CONFIG_MITIGATION_GDSyarch/x86/Kconfig 默认值让内核默认采用AUTO策略在支持微码缓解的机器上自动启用缓解及时更新微码 / BIOS使 CPU 具备GDS_CTRL位 25枚举能力此时缓解状态应显示为Mitigation: Microcode确认状态cat /sys/devices/system/cpu/vulnerabilities/gather_data_sampling预期输出Mitigation: Microcode如果显示Vulnerable: No microcode说明微码尚未更新可临时使用gather_data_samplingforce以内核侧禁用 AVX 的方式降级缓解需评估其对工作负载的性能影响除非有明确的性能/兼容性诉求不要设置gather_data_samplingoff——文档强调该漏洞能跨越用户态/内核态、guest/host、SGX 边界等几乎所有权限边界泄漏陈旧数据虚拟化场景确保宿主启用 GDS 缓解VMM 不应允许 guest 关闭该缓解同时确认 KVM 暴露给 guest 的ARCH_CAP_GDS_NO语义正确见上文 arch/x86/kvm/msrs.c 实现。最后再次强调文档中对用户的兼容性提醒在无新微码、依赖“禁用 AVX”缓解gather_data_samplingforce或clearcpuidavx的机器上CPU 仍会枚举 AVX 能力而 YMM 已被关闭因此依赖 AVX 的用户态程序必须严格遵守“先查 AVX、再查 XSAVE YMM”的双重枚举流程避免因错误假设 AVX 可用而出现运行时故障。关联文档与源码索引本文主体文档Documentation/admin-guide/hw-vuln/gather_data_sampling.rst硬件漏洞文档总览Documentation/admin-guide/hw-vuln/index.rst缓解状态机与命令行解析arch/x86/kernel/cpu/bugs.cCPU 漏洞检测与 MSR 写入arch/x86/kernel/cpu/common.c特性/漏洞位定义arch/x86/include/asm/cpufeatures.h、arch/x86/include/asm/msr-index.hKVM 对 guest 的GDS_NO上报arch/x86/kvm/msrs.c编译期开关arch/x86/Kconfig【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表