Lec 13隔离(Isolation)
Lec 13 隔离(Isolation)
MIT 6.1600 · Introduction to Computer Security
TL;DR
- 隔离要求一个域的行为不能非法影响或泄露给另一个域;非干扰比“没有直接读写”更强,因为它还排除可观察的间接影响。
- 模拟执行、时间复用、地址翻译与软件插桩从不同层面建立边界,虚拟机和浏览器沙箱通常组合多种机制。
- 共享缓存、调度与推测执行仍会形成侧信道,说明功能隔离不等于信息流隔离;缓解需要分区、刷新、随机化或减少共享。
1. 隔离的动机
在云计算、移动平台、浏览器中,多个互不信任的程序共享同一硬件:
- AWS EC2:同一物理机运行多个租户的 VM
- 手机:多个 App 共享同一 CPU 和内存
- 浏览器:多个标签页(origin)并存
当一个组件出现恶意行为或 bug 时,系统需保证其无法影响其他组件——这就是隔离域(Isolation Domain)。
2. 形式化定义
2.1 弱完整性
对手域 A 不能修改受害者域 V 的状态 :
2.2 弱机密性(Non-Leakage)
A 的输出对 V 的状态不敏感:
2.3 非干扰(Non-Interference,强性质)
并发运行时上述性质仍成立:
2.4 为什么非干扰难以实现
只要两个域共享任何资源(CPU 时间、内存容量、磁盘带宽),就存在侧信道(Side Channel):
内存侧信道:
受害者: malloc(secret) # 分配与 secret 成比例的内存
攻击者: 不断 malloc 直到失败 → 推断 secret
时序侧信道:
受害者: 执行时间取决于 secret(如 RSA 幂运算)
攻击者: 测量时间 → 推断 secret
实践:大多数隔离机制放弃严格非干扰,选择"好用"的近似隔离。
3. 实现隔离的机制
隔离实现需回答三个问题:
- 每个域的**状态(State)**是什么?
- 哪些操作会访问状态?
- 如何强制保证操作只影响本域状态?
3.1 模拟执行(Emulation)
解释器逐指令解析并在隔离状态上执行,每条指令前检查权限:
- JavaScript 引擎、Python 解释器
- 优点:实现简单,隔离强
- 缺点:速度慢(每条逻辑指令需多条物理指令);无法利用专用硬件
3.2 时间多路复用(Time Multiplexing)
每次只让一个域运行,切换时:
- 保存当前域的 CPU 寄存器、内存
- 清零硬件状态
- 加载下一个域的状态
- 游戏机的进程切换
- 优点:域内程序可完全控制硬件
- 缺点:上下文切换代价高(需保存/恢复大量状态)
3.3 命名/翻译(Naming / Translation)
隔离程序不能直接访问物理资源——只能通过由隔离机制控制的虚拟指针:
虚拟内存:每个进程的虚拟地址空间映射到独立的物理页,不同进程的虚拟地址指向不同物理内存。
其他例子:
- 文件描述符(Linux):进程只能操作被 OS 分配的文件,不能任意打开
- 虚拟 VLAN(网络):不同虚拟网络共享物理交换机但相互隔离
3.4 软件插桩(Software Interposition)
编译器自动在每次内存访问前插入边界检查:
// 原始代码
var a = b[c];
// 插桩后
if (c >= b.size) error();
load b+c -> a;
程序直接在硬件上运行(无模拟),但代码内部自动执行检查。
挑战:函数指针的处理——若攻击者能控制函数指针的值,可绕过检查跳过安全代码。
4. 案例:虚拟机隔离
状态:寄存器值、内存内容、磁盘数据
操作:CPU 指令(寄存器/内存)、设备 I/O
| 操作类型 | 隔离机制 |
|---|---|
| 寄存器更新 | 时间多路复用(每次一个 VM) |
| 内存访问 | 命名/翻译(虚拟内存,VMM 控制页表) |
| 设备 I/O | 模拟执行(VM 的 I/O 指令陷入 VMM) |
KVM / VMware 使用硬件虚拟化(Intel VT-x / AMD-V)加速切换,减少 VMM 介入。
5. 侧信道攻击(Side-Channel Attacks)
即使完整性和机密性成立,侧信道仍可泄露信息。
5.1 缓存时序侧信道
CPU 缓存(Cache)使内存访问时间不均等:
- 缓存命中:~4 个时钟周期
- 缓存缺失:~200 个时钟周期
若受害者的内存访问模式取决于 secret,攻击者通过测量时间可推断 secret。
5.2 Flush+Reload 攻击
- 攻击者 flush 某共享内存行(使其驱逐出缓存)
- 受害者运行(可能访问该内存行)
- 攻击者 reload 该内存行,测量时间
- 时间短 → 受害者访问了该行 → 推断 secret 的某一位
5.3 Spectre / Meltdown(硬件级侧信道)
利用 CPU 的**推测执行(Speculative Execution)**机制:
- CPU 为了加速会"预测"分支结果并提前执行
- 若预测错误则回退,但缓存状态已被修改
- 攻击者通过缓存侧信道读出推测执行阶段的内存内容
Meltdown(CVE-2017-5754):利用内核页面权限检查延迟,用户进程可读内核内存。
Spectre(CVE-2017-5753/5715):利用分支预测器,可读同进程内其他隔离沙箱的内存。
5.4 缓解措施
| 攻击 | 缓解措施 |
|---|---|
| Meltdown | KPTI(内核页表隔离):用户态不映射内核地址 |
| Spectre | Retpoline(返回地址蹦床);浏览器降低定时器精度 |
| Cache 侧信道 | 常数时间算法(Constant-time programming) |
常数时间编程原则:密码学代码中访问的内存地址和执行时间不依赖秘密数据:
// 错误(时序依赖密钥位)
if (key_bit) access(table[i]);
// 正确(无分支,无条件加载两个值)
uint8_t v0 = table[0][i], v1 = table[1][i];
result = select(key_bit, v0, v1); // 用 bit masking 实现
关键概念总结
| 概念 | 说明 |
|---|---|
| 隔离域 | 相互隔离的执行单元 |
| 非干扰 | A 运行后看不到 V 的任何信息(强理想性质) |
| 侧信道 | 通过共享资源的观察(时间/缓存)泄露信息 |
| Spectre | 推测执行 + 缓存侧信道,突破语言级沙箱 |
| Meltdown | 推测执行突破内核/用户态隔离 |
| KPTI | Meltdown 的 OS 级缓解:用户态不映射内核页 |
我的理解
隔离与资源共享天然冲突;越追求缓存、内存和硬件的复用效率,越需要明确可观察的共享状态。