Linux内核v5.1安全特性解析
发布时间:2019年5月27日
分类:博客、Chrome OS、Debian、内核、安全、Ubuntu、Ubuntu服务器
Linux内核v5.1已正式发布!以下是我关注到的安全相关重要特性:
pidfd的引入
用户空间堆内存映射的显式测试
在Linux Conf AU 2019内核加固会议上,Matthew Wilcox指出内核在用户空间映射应用于内核堆内存时缺乏完整性检查(这可能被攻击者用于绕过copy_{to,from}_user()基础设施)。驱动程序缺陷或被混淆的映射攻击不会被捕获,因此他增加了检查机制。引用提交说明:“将SLAB分配的页面映射到用户空间永远是不合适的"和"使用page_type的页面绝不能映射到用户空间,否则会破坏其页面类型”。后一项检查几乎立即发现了一个错误案例,并迅速修复以避免页面类型损坏。
LSM堆叠:共享安全数据块
Casey Schaufler实现了多个Linux安全模块(LSM)同时运行(称为"堆叠")的关键功能。现在LSM可以共享与各种核心结构(如inode、任务等)关联的安全存储"数据块",LSM可用这些存储空间保存状态(例如存储特定任务受限于哪个配置文件)。内核原本只允许单个活跃的"主要"LSM(如SELinux、AppArmor等)完全控制整个存储块。通过"共享"安全数据块,LSM基础设施负责内存分配和管理,各LSM使用偏移量读写自己的部分。这为"中型"LSM(如SARA和Landlock)与"主要"LSM堆叠铺平了道路,因为它们需要比"次要"LSM(如Yama、LoadPin)存储更多状态,而次要LSM因不需要数据块存储已可堆叠。
SafeSetID LSM
Micah Morton新增了SafeSetID LSM,提供了限制CAP_SETUID能力相关权限的方法。通常具有CAP_SETUID的进程可以成为系统上的任何用户(包括root),这使得向非root用户授予该能力以"降低权限"变得毫无意义。Chrome OS中的进程树需要在不同用户ID下运行,而其他安全实现用户转换的方法不足。该功能通过setuid()(及通过setgid()的组转换)为具有CAP_SETUID能力的进程创建系统级用户ID转换策略,使其成为向需要uid/gid转换的非root进程授予的更实用能力。
持续进行:refcount_t转换
Elena Reshetova继续在内核核心代码(如调度器、futex、perf)中推进refcount_t转换,Anand Jain在btrfs中进行了额外转换。现有转换(主要结合syzkaller)持续在全内核范围内发现错误。
持续进行:隐式fall-through消除
Gustavo A. R. Silva在标记更多隐式fall-through案例方面取得进展。与refcount_t类似,这项工作的突出之处在于发现了大量错误(参见所有"missing break"补丁)。这充分展示了内核通过添加-Wimplicit-fallthrough防止此类错误复现的快速收益。
栈变量初始化包含标量类型
structleak gcc插件(最初移植自PaX)改进了"按引用"覆盖范围,可初始化标量类型(使得"structleak"名称略显不当:现在可防止更多非结构体类型的泄漏)。除非编译器存在错误,这意味着内核中所有栈变量在函数入口处使用前都会被初始化。对于未通过引用传递给函数的变量,-Wuninitialized编译器标志(通过-Wall启用)已确保内核不会构建仅限本地的未初始化栈变量。启用CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL后,所有通过引用传递的变量也将被初始化。这应能消除大部分(若非全部)未初始化栈缺陷,且性能开销极低(对大多数工作负载可忽略不计),但不像GCC_PLUGIN_STACKLEAK(在系统调用退出时清空栈)那样具有减少栈数据生命期的优势。Clang近期获得了类似的自动栈初始化支持,期待gcc原生支持此功能。为评估各种栈自动初始化功能的覆盖范围,我还在lib/test_stackinit.c中编写了回归测试。
以上就是本次更新的全部内容;如有遗漏请告知。v5.2内核开发周期已启动并运行中。 :)
© 2019 – 2022, Kees Cook. 本作品采用知识共享署名-相同方式共享4.0国际许可协议进行许可。