Linux 内核回归:挂起时未擦除 LUKS 加密密钥
Linux 内核回归:挂起时未擦除 LUKS 加密密钥
Linux 6.9(2024 年 5 月)引入的一个回归导致 LUKS 磁盘加密密钥在 suspend‑to‑RAM(挂起到内存)期间仍然驻留在内存中,实际上失效了本应擦除这些密钥的安全机制。该漏洞使得加密数据在笔记本电脑以挂起状态被扣押且仍然通电时,可能通过冷启动攻击或其他 RAM 转储技术被窃取。
根本原因:一次无声的重构失败
本应在线程退出时丢弃加密密钥的预期被破坏,内核对块设备访问的重构导致密钥擦除工具静默失效。问题追溯到一次将块设备访问移植到文件的特定内核提交,该提交与加密代码产生了意想不到的远程交互。
由于系统仍能正常工作——笔记本仍能挂起并恢复而不报错——该回归在两年多的时间里未被发现。正如社区成员所指出的,这类安全漏洞往往不会自行宣布,因为它们不会导致系统崩溃或功能失效。
检测与缓解
该漏洞由 Ingo Blechschmidt 通过源码分析和内存取证相结合的方式发现。在尝试将一个受 Debian 启发的 cryptsetup-suspend 工具集成到 NixOS 时,Blechschmidt 注意到即使文档声称密钥应已被丢弃,/proc/keys 中的条目仍然可见。他在 QEMU 中运行虚拟机并转储内存,确认了卷密钥仍然存在于 RAM 中。
当前修复和变通方案
- 内核补丁:开发了一行内核补丁,解决了物理块设备上加密卷的常见情况。然而,后来指出该补丁不完整,因为它未覆盖虚拟环回设备。
- Cryptsetup 更新:
cryptsetup团队的 Ondrej Kozina 开发了一个规避内核 bug 的变通方案。此修复计划随cryptsetup2.8.7 发行版发布。 - NixOS 实现:为 NixOS 发布了一个实验性的 “安全 suspend‑to‑RAM” 项目,该项目复活了 Pali Rohár 的旧内核补丁,以在挂起时擦除 LUKS 密钥。
- 替代电源状态:关注此漏洞的用户可以使用 suspend‑to‑disk(休眠)。与 suspend‑to‑RAM 不同,休眠会将 RAM 内容写入加密的 swap 分区并关闭内存电源,确保密钥不会以明文形式留在 RAM 中。
威胁模型与技术背景
此修复主要针对 冷启动攻击,即攻击者在物理上接触到一台已通电(但挂起)的机器时,能够转储 RAM 内容以恢复加密密钥。
社区对内存安全的观点
围绕此 bug 的技术讨论突出了多层防御策略:
“如果你的 CPU 支持,启用内存加密……没有明文会离开 CPU 包。DIMM 换出攻击将变得毫无用处。”
其他用户建议利用 TPM 功能,如 MemoryOverwriteRequestControl,以确保在启动时擦除内存。关于 bug 范围也有争论;有些人认为因为 cryptsetup luksSuspend 主要是 Debian 的特定扩展,而非上游 Linux 的核心特性,影响仅限于特定发行版。
修复概览
| 方法 | 安全级别 | 便利性 |
|---|---|---|
| Suspend‑to‑RAM(未打补丁) | 低(密钥留在 RAM) | 高 |
| Suspend‑to‑RAM(已打补丁) | 中(密钥已擦除) | 高 |
| Hibernate(Suspend‑to‑Disk) | 高(RAM 已断电) | 中 |
| 硬件内存加密 | 极高 | 高 |