Linux v5.10 安全特性深度解析:从内存加密到系统调用加固

本文详细介绍了Linux v5.10版本中的多项安全增强特性,包括AMD SEV-ES内存加密、x86静态调用优化、网络随机数生成器改进、SafeSetID组权限控制、内核文件内容检查机制升级等关键技术更新。

Linux v5.10 安全特性

先前版本:v5.9

Linux v5.10 于2020年12月发布。以下是我发现有趣的各种安全特性总结:

AMD SEV-ES

虽然AMD SEV的客户机VM内存加密已支持一段时间,但Joerg Roedel、Thomas Lendacky等人添加了寄存器状态加密(SEV-ES)。这意味着VM主机更难重建客户机VM的状态。

x86静态调用

Josh Poimboeuf和Peter Zijlstra为x86实现了静态调用,其操作方式与内核中的"静态分支"基础设施非常相似。使用静态分支,if/else选择可以硬编码,而不是每次运行时都进行评估。这些分支也可以更新(内核只需重写代码来切换"分支")。所有这些原则也适用于静态调用,但它们用于用直接调用(即硬编码的调用地址)替换间接函数调用(即通过函数指针的调用)。这消除了对这些间接调用进行Spectre缓解(例如RETPOLINE)的需要,并避免了对指针的内存查找。对于热路径代码(如调度程序),这具有可衡量的性能影响。它也是一种控制流完整性实现:间接调用被移除,潜在目标在编译时已明确标识。

网络RNG改进

为了改进网络子系统使用的伪随机数生成器(用于端口号和包序列号等),Linux自制的pRNG已被SipHash轮函数替换,并通过(希望)难以预测的内核内部状态进行扰动。这应该使得暴力破解pRNG内部状态并通过检查网络流量预测未来随机数变得非常困难。类似地,ICMP的全局速率限制器被调整以避免泄露网络状态细节,作为修复最近DNS缓存投毒攻击的开始。

SafeSetID处理GID

Thomas Cedeno改进了SafeSetID LSM以处理组ID(这需要教内核哪些系统调用实际执行setgid)。与早期的setuid策略一样,这允许系统所有者定义在CAP_SETGID下允许的组ID转换的显式列表(而不是任何组),提供了一种使授予此功能的能力更加受限的方法。(但这还不完整,因为还需要处理setgroups()。)

改进内核内部文件内容检查

内核在加载文件时向LSM(如完整性子系统)提供文件详细信息。(例如,加载模块、kexec的新内核映像和固件。)对于内容来自非文件的情况,覆盖范围不是很好。为了解决这个问题,添加了新的钩子,允许LSM直接内省内容并进行部分读取。这将使LSM对此类操作具有更细粒度的可见性。

set_fs移除继续

随着早期工作的落地,使核心内核代码摆脱set_fs(),Christoph Hellwig使set_fs()对体系结构成为可选的。随后,他完全移除了x86、riscv和powerpc的set_fs()。这些体系结构现在将免受整个"内核地址限制"攻击类的影响,这些攻击只需要破坏struct thead_info中的单个值。

sysfs_emit()替换/sys中的sprintf()

Joe Perches通过创建一个新的辅助函数sysfs_emit(),解决了/sys处理程序中sprintf()和snprintf()最常见的一类错误。这将处理内核代码未正确处理sprintf()调用的长度结果的情况,这可能导致/sys处理程序操作的PAGE_SIZE缓冲区中的缓冲区溢出。有了这个辅助函数,可以开始重构许多sprintf()调用者。

nosymfollow挂载选项

Mattias Nissler和Ross Zwisler实现了nosymfollow挂载选项。这完全禁用给定文件系统的符号链接解析,类似于其他挂载选项,其中noexec不允许execve(),nosuid不允许setid位,nodev不允许设备文件。引用补丁,它"作为防御措施有用,用于需要在特权上下文中处理不受信任文件系统的系统。"(即当/proc/sys/fs/protected_symlinks不够强大时。)Chrome OS为其有状态文件系统使用此选项,因为符号链接遍历一直是常见的攻击持久性向量。

ARMv8.5内存标记扩展支持

Vincenzo Frascino为arm64添加了对即将到来的内存标记扩展的支持,该扩展将可用于ARMv8.5及更高版本的芯片。它提供4位标签(覆盖地址空间的16字节跨度的倍数)。这足以确定性地消除所有线性堆缓冲区溢出缺陷(1个标签用于"空闲",然后为相邻分配旋转偶数值和奇数值),这可能是当前被利用的最常见错误之一。它还使攻击者更难进行释放后使用和过度/不足索引(但如果目标的标签位可以暴露,仍然可能)。也许有一天我们可以切换到128位虚拟内存地址并进行完全版本化的分配。但目前,16个标签值比没有好,尽管我们仍然需要等待任何人实际发货ARMv8.5硬件。

UBSAN发现的缺陷修复

使UBSAN在syzkaller下普遍可用的工作继续取得成果,内核各处对各种问题进行了修复,如移位越界、除零和整数溢出。看到这些类型的补丁落地,强化了将这些类型的检查负担转移到工具链的理由:这些运行时错误继续出现。

灵活数组转换

灵活数组转换的工作继续。Gustavo A. R. Silva和其他人继续努力进行转换,使内核越来越接近能够启用-Warray-bounds编译器标志,并为数组索引和memcpy()使用的更合理边界检查清除道路。

目前就这些!如果您认为还有其他需要关注的地方,请告诉我。接下来是Linux v5.11。

© 2022, Kees Cook。本作品采用知识共享署名-相同方式共享4.0许可协议授权。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计