2018 年 Meltdown/Spectre 公开后,内核为每次系统调用多做了大量安全工作——这些缓解措施的代价是什么?
一、先看图
flowchart TD
VULN[CPU 漏洞] --> MELTDOWN[Meltdown<br/>内核内存泄露]
VULN --> SPECTRE[Spectre v1/v2<br/>分支预测攻击]
VULN --> MDS[MDS/L1TF/BHI<br/>微架构攻击]
MELTDOWN --> KPTI[KPTI<br/>页表隔离]
SPECTRE --> RETPO[retpoline<br/>间接跳转保护]
SPECTRE --> IBRS[IBRS/eIBRS<br/>硬件缓解]
MDS --> FLUSH[缓冲区刷新]
classDef vuln fill:#f8514922,stroke:#f85149,color:#adbac7;
classDef mit fill:#388bfd22,stroke:#388bfd,color:#adbac7;
class VULN,MELTDOWN,SPECTRE,MDS vuln
class KPTI,RETPO,IBRS,FLUSH mit
二、KASLR
Kernel Address Space Layout Randomization:
每次启动 → 内核加载地址随机 → 攻击者无法预测地址
# 检查 KASLR
grep -i kaslr /proc/cmdline
dmesg | grep "KASLR"配合 kptr_restrict=1 →
/proc/kallsyms 对非 root 隐藏地址。
三、KPTI(Meltdown 缓解)
3.1 原理
用户态和内核态使用不同的页表 → 用户态页表不映射内核内存。
3.2 开销
每次 syscall / 中断 → 切换页表(CR3)→ TLB flush。
PCID(Process Context ID)减轻开销:不同页表使用不同 PCID → 避免全量 TLB flush。
3.3 硬件修复
新 CPU(Intel 10代+)硬件修复 Meltdown → KPTI 可关闭。
四、Retpoline(Spectre v2 缓解)
; retpoline: 用 return 替代间接 call/jmp
call retpoline_trampoline
retpoline_trampoline:
pause
lfence
jmp retpoline_trampoline ; 永远不执行间接分支预测被引导到无限循环 → 推测执行无法泄露数据。
五、IBRS / eIBRS
硬件缓解 Spectre v2:
| 机制 | 说明 |
|---|---|
| IBRS | Indirect Branch Restricted Speculation |
| eIBRS | Enhanced IBRS(更高效) |
| STIBP | Single Thread Indirect Branch Predictor(SMT 保护) |
eIBRS 在新 CPU 上 → 可以不用 retpoline → 性能更好。
六、其他缓解
| 漏洞 | 缓解 | 开销 |
|---|---|---|
| L1TF | L1D flush on vmentry | 低 |
| MDS | 缓冲区刷新 | 中 |
| SSBD | Speculative Store Bypass Disable | 中 |
| BHI | Branch History Injection → 清除 BHB | 低 |
| Retbleed | return 指令推测 → IBPB/unret | 中 |
七、性能影响
# 查看当前缓解状态
grep . /sys/devices/system/cpu/vulnerabilities/*典型开销:
| 场景 | KPTI 开销 | retpoline 开销 |
|---|---|---|
| syscall 密集 | 5-30% | 2-8% |
| I/O 密集 | 2-5% | 1-3% |
| 计算密集 | < 1% | < 1% |
八、mitigations= 参数
# 关闭所有缓解(不推荐生产使用)
mitigations=off
# 自动(默认)
mitigations=auto
# 自动 + SMT 可能被禁用
mitigations=auto,nosmt九、观察
# 漏洞与缓解状态
grep . /sys/devices/system/cpu/vulnerabilities/*
# 当前使用的 spectre 缓解
dmesg | grep -i spectre
dmesg | grep -i "page table isolation"
# 性能对比
perf stat -e instructions,cycles -- ./workload
# 对比 mitigations=off(仅测试环境!)十、小结
- KASLR 随机化内核地址 → 增加攻击难度
- KPTI 隔离用户态/内核态页表 → 缓解 Meltdown
- retpoline 保护间接分支 → 缓解 Spectre v2
- eIBRS 硬件缓解更高效
- 缓解措施有真实性能开销 → 新硬件逐步降低
参考文献
Documentation/admin-guide/hw-vuln/arch/x86/mm/pti.c(KPTI)arch/x86/lib/retpoline.S- Jonathan Corbet, “The current state of kernel page-table isolation.” LWN 2018
工具
/sys/devices/system/cpu/vulnerabilities/dmesgspectre-meltdown-checker
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【操作系统百科】特权级与硬件隔离:ring0、EL、SMEP/SMAP/PKU/CET
OS 的隔离能力在哪里落地?CPU 提供了特权级、MMU、MPU、enclave、VMX 等一串原语,OS 把它们组合成进程/用户/内核/hypervisor 等隔离层级。本文从 x86 ring 0-3、SMM、ARMv8 EL0-3 起步,梳理 SMEP/SMAP/PAN、KPTI、CET、MTE、PKU、IBRS 等缓解机制,说清楚每一项挡的是哪一类攻击。
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。
【操作系统百科】交换
swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。
【操作系统百科】Slab/SLUB 分配器
buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。