Linux内核v4.17安全特性
Linux内核v4.17于上周发布,以下是我认为有趣的一些安全相关内容:
Jailhouse hypervisor
Jan Kiszka引入了Jailhouse hypervisor支持,该功能采用静态分区(即无资源过度分配),根“单元”通过缩减自身的CPU/内存等资源来生成新监狱,并将这些资源移交新监狱。2014年LWN上有一篇关于该hypervisor的详细文章。
Sparc ADI
Khalid Aziz添加了对Sparc应用数据完整性(ADI或SSM:硅安全内存)的用户空间支持,这是Sparc M7中的硬件内存着色(标记)功能。我希望将其扩展到内核本身,因为它可以消除分配之间的线性溢出,因为使用的基础指针被标记为仅属于特定分配(大小与缓存行倍数对齐)。任何尝试递增超出范围、进入具有不同标记的内存的行为都会引发异常。Enrico Perla有一些关于在分配器中使用ADI以及将ADI与Intel MPX进行比较的优秀文章。
新内核栈在fork时清零
旧内存内容可能存在于新进程的内核栈中。虽然通常不可见,但“未初始化”内存读取缺陷或读取溢出可能暴露这些内容(尤其是栈中“更深”的内容,可能在进程生命周期内从未被覆盖)。为避免这种情况,我确保新栈始终被清零。奇怪的是,这种缓存“预热”似乎实际上提高了性能,尽管大部分在噪声中。
MAP_FIXED_NOREPLACE
作为针对Stack Clash等攻击的深度防御的一部分,Michal Hocko创建了MAP_FIXED_NOREPLACE。常规MAP_FIXED有一个通常不被注意的微妙行为(但被某些人使用,因此无法简单修复):它将替换任何预先存在映射的重叠部分。这意味着内核会静默地将栈重叠到mmap或文本区域,因为MAP_FIXED被用于构建新进程的内存布局。相反,MAP_FIXED_NOREPLACE具有MAP_FIXED的所有功能,但没有替换行为:如果预先存在的映射与新请求的映射重叠,它将失败。ELF加载器已切换为使用MAP_FIXED_NOREPLACE,并且它也适用于用户空间的类似用例。
在exec期间固定栈限制
我使用了一种强硬方法,在exec期间固定了RLIMIT_STACK值。有多种方法可以更改限制(至少通过setrlimit()和prlimit()),并且有多个地方使用该限制做出决策,因此似乎最好在exec生命周期内固定这些值,以免被玩弄。太多假设该值不会改变,因此最好使该假设成立。希望这是exec期间栈限制和内存布局之间不良交互的最后修复(这些都是针对Stack Clash等缺陷的防御措施)。
可变长度数组移除开始
在Alexander Popov持续移植stackleak GCC插件的一些讨论之后,Linus宣布应完全从内核中消除可变长度数组(VLA)。这很好,因为它消除了几种栈耗尽攻击,包括通过巨大栈分配跨越保护页的奇怪行为。然而,内核中有数百处使用,这不是一项容易的工作。幸运的是,一大批人站出来帮忙:Gustavo A. R. Silva、Himanshu Jha、Joern Engel、Kyle Spiers、Laura Abbott、Lorenzo Bianconi、Nikolay Borisov、Salvatore Mesoraca、Stephen Kitt、Takashi Iwai、Tobin C. Harding和Tycho Andersen。与Linus Torvalds和Martin Uecker一起,我还帮助重写了max()宏,以消除-Wvla编译器选项看到的误报。总体而言,v4.17解决了约1/3的VLA实例,v4.18将解决更多。我希望在v4.19发布时完全消除VLA。
编辑:我最初发布此帖子时错过了以下功能:
x86系统调用寄存器清理
攻击者影响内核中潜在推测执行缺陷的一种方法是通过“未使用”的寄存器内容将信息泄漏到内核中。大多数系统调用仅接受几个参数,因此所有其他调用约定定义的寄存器可以被清理,而不是仅保留它们在用户空间中的内容。事实证明,清理寄存器非常快。Dominik Brodowski将Linus Torvalds的概念验证扩展为x86上的完整寄存器清理系统调用包装器。
目前就这些!如果您认为我遗漏了什么,请告诉我。请继续关注v4.18;合并窗口已打开。
© 2018, Kees Cook。本作品采用知识共享署名-相同方式共享4.0许可协议授权。