土法炼钢兴趣小组的算法知识备份

【操作系统百科】特权级与硬件隔离:ring0、EL、SMEP/SMAP/PKU/CET

文章导航

分类入口
os
标签入口
#privilege-levels#ring0#smep#smap#kpti#cet#mte#pku#mitigations#armv8

目录

【操作系统百科】特权级与硬件隔离

CPU 是唯一能强制执行”用户态不能做什么”的东西。OS 把软件抽象(进程、namespace、capability)最终都要落到 CPU 提供的硬件原语——特权级、分页、某些特殊指令的拦截——才算数。如果 CPU 的隔离机制失效(Meltdown 就是经典例子),再完美的软件隔离都会被一句 mov rax, [kernel_addr] 破掉。

本文把 CPU 给 OS 的隔离原语梳理清楚。按层次从”经典”到”现代缓解”:特权级本体 → 页表保护位 → SMEP/SMAP/PAN → KASLR/KPTI → CET / BTI / MTE → PKU/PKRU → 硬件加密内存 → VMX root/non-root → SMM/TrustZone。每一项挡的攻击类型不同,组合起来构成了现代系统的”深度防御”。

下面这张图把 x86 / ARMv8 / RISC-V 三家的特权级层次并排摆出,方便比较:

flowchart TB
    subgraph x86[x86_64]
        direction TB
        X3[Ring 3 / 用户态<br/>应用]
        X0[Ring 0 / 内核]
        XV[VMX root / Hypervisor]
        XS[SMM / 固件]
        X3 --> X0 --> XV --> XS
    end
    subgraph ARM[ARMv8-A]
        direction TB
        A0[EL0 / 用户态]
        A1[EL1 / 内核]
        A2[EL2 / Hypervisor]
        A3[EL3 / Secure Monitor<br/>TrustZone]
        A0 --> A1 --> A2 --> A3
    end
    subgraph RV[RISC-V]
        direction TB
        RU[U-mode / 用户]
        RS[S-mode / 内核]
        RH[HS-mode / Hypervisor]
        RM[M-mode / 固件]
        RU --> RS --> RH --> RM
    end

箭头方向是”权限递增”。x86 的 SMM 是”暗层”——OS 无法感知;ARM 的 EL3 与 RISC-V 的 M-mode 是固件层,机密计算和 TrustZone 的信任根都挂在它上面。后面几节围绕这张图展开:页表保护是 ring 0 与 ring 3 之间的执行细则;VMX 是在 ring 0 之上叠加的 hypervisor 层;SEV/TDX 甚至让 ring 0 的 hypervisor 也不可信。

一、特权级:最原始的隔离

1.1 x86 的 ring 0–3

Intel 80286(1982)引入四级特权:

特权级不是一个独立的寄存器,而是 编码在 CS 段选择子的低两位(CPL,Current Privilege Level)。每次段切换或中断都可能触发 CPL 变化。Linux 和 Windows NT 都只用 ring 0 和 ring 3。ring 1、ring 2 在 VMware 二进制翻译时代曾被用来跑 guest 内核,硬件虚拟化成熟后基本退役。

关键限制:CPL 只检查”要不要允许这条指令”,不检查”要不要允许访问这块内存”。访问控制是页表的工作(下一节)。这是为什么 Meltdown 能绕过特权级——它不是通过执行特权指令,而是通过”推测性执行 + cache 侧信道”读取内核地址。

1.2 SMM:比 ring 0 还高的秘密

System Management Mode(SMM)是 Intel 系统管理模式,由固件和 BIOS 使用。它:

SMM 代码跑在 “ring -2”(常见说法)。它可以访问所有物理内存,OS 几乎无法检测到 SMI 的发生(除非通过 TSC 差值间接推测)。SMM 漏洞(如 2015 年的 BIOS 更新 bug)可以绕过所有 OS 级防护。

OS 对 SMM 的态度:尽量减少 SMI 的发生(延迟敏感系统会要求固件供应商禁用可选 SMI),但无法彻底根除。机密计算(L-108 机密计算)的一个目标就是把 SMM 从 TCB 里踢出去。

1.3 ARMv8 的 EL0–3

ARM 走了不同的路线——Exception Level:

ARMv8 的 EL2 设计原本是 “thin layer for hypervisor”。为了解决 Linux 作为 guest 的性能问题,ARMv8.1 加入了 VHE(Virtualization Host Extensions)和 E2H bit,允许主机 OS 直接跑在 EL2 上,把 guest EL1 跑在 EL1,消除了 Host OS ↔︎ hypervisor 的上下文切换开销。KVM on ARM 就是这么跑的。

EL3 与 TrustZone:EL3 执行 secure monitor,负责在 secure world(TEE)和 normal world(普通 OS)之间切换。Android 的 Keymaster、iOS 的 Secure Enclave 等都是在 TrustZone 里跑。

1.4 RISC-V 的 M/S/U

RISC-V 简洁明了:M(Machine)S(Supervisor)U(User)。可选 HS(Hypervisor-extended Supervisor)给虚拟化用。

RISC-V 的 PMP(Physical Memory Protection)和 PMA(Physical Memory Attributes)给 M mode 提供了独立于页表的物理内存访问控制——这在嵌入式 RISC-V 场景非常有用(无 MMU 时的保护)。

二、页表保护:真正的内存隔离

特权级不控制内存访问;页表控制。x86_64 的 PTE(Page Table Entry)里有几个关键位:

2.1 U/S 位:区分内核页和用户页

内核页表里,U/S = 0 标记内核私有页;U/S = 1 标记用户可访问页。Ring 3 执行时,CPU 拒绝访问 U/S = 0 的页,发 #PF(Page Fault)。

漏洞:Meltdown(2018)证明了 CPU 在推测性执行时 可以临时读取 U/S = 0 的内核页并把值载入缓存,即使随后的访问检查会回滚指令,cache 状态不回滚。攻击者通过 timing 侧信道读出 cache 差异,反推内核数据。

缓解 KPTI(Kernel Page Table Isolation,2018):给每个进程维护两套页表,用户态模式下的页表里几乎没有内核映射(只保留中断入口、vDSO 等最小必要部分)。这样即使 Meltdown 能读,也无可读。

代价:每次 syscall / 中断进入/退出都要切换 CR3(页表根),增加 TLB miss。Linux 在 Skylake 上实测 open/close 循环延迟增加 15–30%。Intel 后续在 Coffee Lake(2018)硬件修复 Meltdown,KPTI 可关闭(mitigations=off)。

2.2 NX 位:防止数据区代码执行

NX 位(AMD 的 “NX”、Intel 的 “XD”)禁止对应页上的代码被执行。

NX 不阻止 ROP/JOP(Return-Oriented Programming)——那是 CET 要解决的。

2.3 SMEP / SMAP / PAN

这三项是 2010 年代最重要的内核硬件防护演进。2011 年之前内核经常被 “用户态 pivot” 类攻击得手;有了 SMEP/SMAP 后这类利用难度大幅上升。

三、KASLR:让攻击者找不到目标

KASLR(Kernel Address Space Layout Randomization)在启动时把内核加载到一个随机地址(典型偏移范围 1GB)。目的:让攻击者即使有内核漏洞也不知道要跳到哪里。

弱点

KASLR 不是根本性防御,是”提高攻击成本”的阶梯。它必须配合其他机制(KPTI、CET、lockdown)使用。

四、投机执行缓解:Spectre / Meltdown 家族

2018 年 1 月 3 日,Jann Horn、Paul Kocher 等人联合披露 Meltdown(CVE-2017-5754)和 Spectre(CVE-2017-5753 / 5715)。这是 OS 安全史上的一个分水岭——在这之前大家觉得 CPU 硬件是可信的。

4.1 Meltdown

利用:推测性越权读取内核内存

缓解:KPTI。软件层的 page table 隔离。

4.2 Spectre v1(Bounds Check Bypass)

利用:推测性执行越过边界检查

缓解:

4.3 Spectre v2(Branch Target Injection)

利用:污染 BTB(Branch Target Buffer),让推测性执行跳到攻击者选择的地址

缓解:

4.4 后续变种

Spectre v3a、v4、SSB(Speculative Store Bypass)、L1TF(L1 Terminal Fault)、MDS(Microarchitectural Data Sampling)、ZombieLoad、RIDL、Fallout、TAA、SRBDS、Retbleed、Downfall……

每一种都对应一个微码补丁或内核缓解。Linux 内核在 /sys/devices/system/cpu/vulnerabilities/ 下列出了当前机器对每一种漏洞的暴露状态:

$ grep . /sys/devices/system/cpu/vulnerabilities/*
.../meltdown:          Mitigation: PTI
.../spectre_v1:        Mitigation: usercopy/swapgs barriers and __user pointer sanitization
.../spectre_v2:        Mitigation: Retpolines, STIBP: conditional, IBPB: conditional
.../srbds:             Mitigation: Microcode
.../tsx_async_abort:   Not affected
...

工程影响:这些缓解在某些 workload 上累计性能代价可达 10–30%。生产环境选择性禁用(mitigations=off)是常见但危险的做法。

五、控制流完整性:CET 与 BTI

即使内存执行/写权限分清楚了,攻击者仍可通过 ROP(Return-Oriented Programming)利用合法代码片段组合执行恶意逻辑。Intel CET 和 ARM BTI 是硬件级别的控制流保护。

5.1 Intel CET(Tiger Lake+ / Sapphire Rapids)

两部分:

Linux 6.6+ 在支持的 CPU 上可启用 user space CET(glibc 2.28+ 编译时 -fcf-protection)。内核内 CET 支持在持续推进。

5.2 ARM BTI / PAC

PAC 比 CET SHSTK 更精细——它保护任意指针(包括 C++ vtable、函数指针),不只是返回地址。iOS 的 PAC 使用是 PAC 在消费级的最大规模部署。

六、内存标记:MTE

MTE(Memory Tagging Extension,ARMv8.5)给每 16 字节内存分配一个 4-bit 标签,指针的高位也带标签;硬件在访问时比对标签。

用途:检测 use-after-free 和 buffer overflow

模式:

Android 从 Pixel 8(2023)开始在内核和应用态广泛启用 MTE。它被认为是”内存安全的硬件补丁”——对于无法用 Rust 重写的 C 代码是有效止损。

七、PKU / PKRU:进程内权限分区

PKU(Protection Keys for Userspace,Skylake-X 2016+)允许同一地址空间内的不同页被打上 key(0–15),每个线程的 PKRU 寄存器控制哪些 key 可读/可写。

典型用途:

与 SMAP 区别:SMAP 是内核/用户分界;PKU 是进程内分区。两者独立。

内核内也有 PKS(Protection Keys for Supervisor,Icelake+)做内核内部页权限分区,但目前 Linux 使用很少。

八、地址空间隔离的硬件辅助:ASID、PCID、VPID

让 TLB 不跨地址空间失效,是降低 KPTI / 虚拟化切换开销的关键。

九、VMX / SVM:硬件虚拟化

Intel VMX(VT-x)和 AMD SVM 把”运行 guest”变成硬件特性:

性能优化:

这些优化让 KVM 在网络和 I/O 密集场景的开销降到 10% 以内。L-101、L-102 会详细展开。

十、机密计算:SEV / TDX / CCA

传统虚拟化下,hypervisor 可读所有 guest 内存——这对云厂商自己想做 “即使云运营者也不能偷看客户数据” 是过不去的。机密计算(Confidential Computing)通过硬件加密 + attestation 解决:

机密计算带来的 OS 设计影响:

  1. Hypervisor 不再可信,必须最小化
  2. I/O 路径需要 “swiotlb” 或 secured DMA(加密边界在 CPU 内部 vs PCIe 边界)
  3. Measurement/attestation 成为必要流程
  4. OS 自己要适配(Linux 有 coco/ 子系统专门处理机密 guest)

M-108 会细讲。

十一、小结:深度防御的层次表

现代系统把所有这些机制叠起来:

                                   目的
ring 0/3                          基础特权分离
U/S, W, NX (页表)                 细粒度内存权限
SMEP / SMAP / PAN                 禁止内核执行/访问用户页
NX + DEP                          阻止数据区执行
KASLR                             随机化减少攻击确定性
KPTI                              隔离内核与用户页表(对抗 Meltdown)
Retpoline / IBRS / eIBRS         对抗 Spectre v2
LFENCE / array_index_nospec      对抗 Spectre v1
CET (SHSTK + IBT)                 阻止 ROP/JOP
BTI / PAC                         ARM 的 CFI + 指针认证
MTE                               检测 UAF / overflow
PKU / PKRU                        进程内权限分区
PCID / ASID / VPID                减少 TLB flush 开销
VMX / SVM + EPT/NPT               虚拟化隔离
SEV / TDX / CCA                   机密计算(不信 hypervisor)
TrustZone / SMM                   专门的高特权环境

没有任何一项是万能的。KPTI 挡不住 Spectre;NX 挡不住 ROP;CET 挡不住类型混淆;MTE 有假阴性;机密计算的 attestation 有供应链信任问题。这是为什么现代内核的 arch/ 目录里 “hardware mitigations” 的代码量在过去十年膨胀了数倍——每一个新漏洞都留下一段新代码

对你设计/审阅系统的意义:

下一篇 A-05 系统调用 ABI 进入 OS 与应用的接触面——当用户代码要请求内核做事,这个跨特权级的跳跃在各架构是如何实现的。


参考文献

工具与源码


上一篇宏内核 vs 微内核 下一篇系统调用 ABI

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-22 · os

【操作系统百科】ARMv8 VMSA 页表

ARMv8-A 翻译体制与 x86 差异很大:两套 TTBR、可选 4K/16K/64K granule、ASID 原生标签、nG/G 分离。本文梳理 VMSAv8-64 核心:TTBR0/1、granule、descriptor、ASID、VHE、MTE、BTI。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。


By .