Linux内核v4.16中的安全特性
Linux内核v4.16于上周发布。尽管我应该提前撰写这些文章,但合并窗口期总是让人分心。无论如何,以下是我认为有趣的一些安全相关内容:
ARM64上的KPTI
Will Deacon、Catalin Marinas等人将内核页表隔离(通过CONFIG_UNMAP_KERNEL_AT_EL0)引入ARM64。虽然大多数ARMv8+ CPU不易受主要Meltdown漏洞影响,但Cortex-A75确实需要KPTI来防止内存内容泄露。值得注意的是,KPTI确实保护其他ARMv8+ CPU模型免于特权寄存器内容暴露。因此,无论您的威胁模型如何,为所有ARMv8+ CPU提供内核与用户空间页表之间的这种清晰隔离都非常有益。
加固用户复制白名单
虽然CONFIG_HARDENED_USERCOPY中已实现全对象边界检查,但David Windsor和我完成了grsecurity的PAX_USERCOPY保护的另一个移植部分:用户复制白名单。这进一步限制了可复制到/从用户空间的slab分配范围。现在,不再允许复制slab内存中的所有对象,只有白名单区域(子系统特别标记允许的内存区域)可以被复制。例如,仅从较大的mm_struct中复制auxv数组。
如该系列的第一个提交所述,这将在面对错误时将可从内核复制的slab内存范围减少到15%以下。可以看出,剩余的一个工作领域是kmalloc区域。这些区域经常用于复制进出用户空间的内容,但它们也用于不打算暴露给用户空间的小型简单分配。分离这些kmalloc用户需要进行一些仔细的审计。
总Slab内存:48074720 可用户复制内存:6367532(13.2%)
- task_struct:0.2%(4480/1630720)
- RAW:0.3%(300/96000)
- RAWv6:2.1%(1408/64768)
- ext4_inode_cache:3.0%(269760/8740224)
- dentry:11.1%(585984/5273856)
- mm_struct:29.1%(54912/188448)
- kmalloc-8:100.0%(24576/24576)
- …(其他kmalloc区域均为100%)
这个系列花了相当长的时间才落地(您可以看到David的原始补丁日期可以追溯到去年六月)。部分原因是必须花费大量时间研究代码路径,以便为提交日志解释每个白名单,部分原因是根据维护者的反馈进行各种调整,部分原因是v4.15的短暂合并窗口(当它最初提议合并时)结合一些最后一刻的故障让Linus感到紧张。在linux-next中烘焙了近两个完整的开发周期后,它终于落地。(但请确保禁用CONFIG_HARDENED_USERCOPY_FALLBACK以强制执行白名单——默认情况下它仅警告并回退到全对象检查。)
自动栈保护器
虽然内核的栈保护器功能已存在相当长的时间,但从未默认启用。这主要是由于需要评估编译器对该功能的支持,而Kconfig在提供CONFIG_*选项之前无法检查编译器功能。作为一种防御技术,栈保护器相当成熟。默认启用它会大大减少像BlueBorne攻击(CVE-2017-1000251)这样的影响,因为更少的系统会缺乏这种防御。
在花费相当多时间与古老编译器版本(咳咳GCC 4.4.4咳咳)斗争后,我落地了CONFIG_CC_STACKPROTECTOR_AUTO,它默认开启,并尝试使用栈保护器(如果可用)。然而,该解决方案的实现并未让Linus满意,尽管他允许合并。未来,Kconfig将获得做出更好决策的知识,让内核直接在Kconfig中暴露(现在默认的)栈保护器的可用性,而不是依赖相当丑陋的Makefile技巧。
PowerPC的执行仅内存
类似于v4.6中为x86引入的保护密钥(pkeys)硬件支持,Ram Pai为Power7/8/9落地了pkeys支持。这应扩展动态加载器中可能的内容,避免任意读取缺陷允许利用读取所有可执行内存以查找ROP小工具。
目前就这些;如果您认为我应该添加任何内容,请告诉我!v4.17合并窗口已打开。:)
编辑:添加了关于ARM寄存器泄露的详细信息,感谢Daniel Micay。 编辑:添加了关于POWER保护密钥的部分,感谢Florian Weimer。
© 2018 – 2019, Kees Cook。本作品根据知识共享署名-相同方式共享4.0国际许可协议授权。