Linux v5.5 内核安全特性深度解析

本文详细介绍了Linux内核v5.5版本中的多项安全增强特性,包括perf事件限制、通用refcount_t实现、异常表清理、KASLR扩展、seccomp支持等,涵盖架构优化与漏洞防护机制。

Linux v5.5 中的安全特性

先前版本:v5.4

我在这篇博客系列中有点落后了!让我们赶上进度。以下是我在 Linux 内核 v5.5 发布中发现的一些有趣的安全相关内容:

通过 LSM 限制 perf_event_open()

鉴于 perf 子系统中反复出现的缺陷,一直有强烈愿望能够完全禁用该接口。虽然 kernel.perf_event_paranoid sysctl 旋钮已经存在一段时间,但过去尝试将其控制扩展到“阻止所有 perf_event_open() 调用”都失败了。发行版内核多年来一直携带被拒绝的 sysctl 补丁,但现在 Joel Fernandes 实现了一个被认为可接受的解决方案:不是扩展 sysctl,而是添加 LSM 钩子,以便 LSM(如 SELinux、Apparmor 等)可以将这些选择作为其整体系统策略的一部分。

通用快速完整 refcount_t

Will Deacon 将最近针对 x86 和 arm64 的 refcount_t 强化工作提炼成一个与架构无关的单一 C 版本。结果几乎与 x86 汇编版本一样快,但覆盖了更多情况(例如从零递增),并且现在默认可用于所有架构。(不再有任何与 refcount_t 相关的 Kconfig;使用该原语提供全面覆盖。)

异常表的链接器脚本清理

当 Rick Edgecombe 展示他在虚拟机监控程序下构建仅执行内存的工作时,他注意到内核试图直接读取(而不是执行)的一个内存区域。他为他的仅 x86 补丁系列重新安排了内容以解决这个问题。由于我刚刚在这个领域工作,我意识到这个问题的根本原因是异常表的位置(它严格来说是一个查找表,从不执行),并构建了一个修复程序,并将其应用于所有架构,因为事实证明几乎所有架构的异常表都只是一个数据表。希望这将有助于为所有架构上更多的仅执行内存工作扫清道路。在这个过程中,我还更新了 x86 上的段填充字节为陷阱(0xCC,int3),而不是 NOP 指令,因此函数需要被攻击更精确地定位。

32 位 PowerPC 的 KASLR

加入许多其他架构,Jason Yan 为 32 位 PowerPC 添加了内核文本基地址偏移随机化(KASLR)。

RISC-V 的 seccomp

经过一段漫长的道路,David Abdurachmanov 为 RISC-V 架构添加了 seccomp 支持。该系列在 seccomp 自测试代码中发现了更多边缘情况,这总是很好,因为这样我们可以使其在未来更加健壮!

seccomp USER_NOTIF 继续

当添加 seccomp SECCOMP_RET_USER_NOTIF 接口时,似乎它只会在非常有限的条件下使用,因此需要处理“正常”请求的想法似乎并不非常繁重。然而,从那时起,很明显,监控进程需要代表被监控进程执行大量“正常” open() 调用的开销开始看起来越来越慢和脆弱。为了解决这个问题,很明显需要一种方式让 USER_NOTIF 接口指示 seccomp 应该正常继续并允许系统调用,而无需任何特殊处理。Christian Brauner 实现了 SECCOMP_USER_NOTIF_FLAG_CONTINUE 来完成这个。它附带了一点免责声明,因为监控器可能会在 ToCToU 有风险的地方使用它,并且可能与 SECCOMP_RET_TRACE 冲突。但总体而言,这对容器监控工具来说是一个净收益。

x86 的 EFI_RNG_PROTOCOL

一些 EFI 系统提供随机数生成器接口,这对于在非常早期的启动期间在内核中获得一些熵很有用。arm64 启动存根已经使用这个一段时间了,但 Dominik Brodowski 现在为 x86 添加了支持以做同样的事情。这个熵对于执行非常早期初始化需要随机数的内核子系统(如随机化 SLUB 内存分配器的各个方面)很有用。

MIPS 的 FORTIFY_SOURCE

正如在许多其他架构上启用的一样,Dmitry Korotin 让 MIPS 使用 CONFIG_FORTIFY_SOURCE 构建,因此在调用 memcpy() 和 strcpy() 系列函数期间,编译时(和一些运行时)缓冲区溢出将被检测到。

限制 copy_{to,from}_user() 大小为 INT_MAX

正如为 VFS、vsnprintf() 和 strscpy() 所做的那样,我继续将 copy_to_user() 和 copy_from_user() 调用的大小限制为 INT_MAX,以捕获大小计算中的任何奇怪溢出。

其他事项

Alexander Popov 指出了一些我在这篇博客文章中遗漏的更多 v5.5 特性。我在这里重复它们,并做了一些小的编辑/澄清。谢谢 Alexander!

  • KASan 对 vmap 内存的支持将 KASan 的功能扩展到包括使用 vmalloc() 分配的内存的分析。更具体地说,这意味着 KASan 可以再次检查堆栈,因为自引入 CONFIG_VMAP_STACK 以来,它可以在该区域。
  • MIPS 现在可以使用 GCC 插件和 KCOV 构建,为这些系统提供相关功能,如堆栈擦除、覆盖分析等。
  • userfaultfd 需要 CAP_SYS_PTRACE 用于 UFFD_FEATURE_EVENT_FORK。这样做是为了阻止非特权用户滥用 userfaultfd 功能,因为它以实现的方式提供了将文件描述符注入到不知情进程中的能力。

编辑:添加了 Alexander Popov 的注释

这就是 v5.5 的内容!如果还有其他我应该在这里指出的内容,请告诉我。接下来:Linux v5.6。

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

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