Linus 震怒!内核整数溢出“安全”之争:从华为案例看 Linux Kernel 的硬核防御演进
前言在 C 语言的世界里整数溢出就像一个潜伏在暗处的幽灵。你以为 $2^{31}-1 1$ 会变成一个巨大的正数结果它却变成了一个负数。这种“数学奇点”在内核空间往往意味着系统权限的彻底丧失。最近内核社区围绕“陷阱整数”展开了一场长达一年的技术博弈。Linus Torvalds 的亲自下场开喷让原本枯燥的补丁讨论变成了关于“什么才是真正的安全”的哲学思辨。一、 深度复盘华为 HSO 驱动漏洞CVE-2021-39290作为 Linux 内核的重要贡献者华为在追求极致性能的同时也时刻在与底层的算术错误作斗争。这个著名的漏洞生动地展示了一个简单的加法是如何毁掉整个系统防御的。1. 漏洞成因消失的边界检查在华为维护的hso网络驱动中处理数据包skb时需要计算缓冲区的总长度。// 简化后的逻辑 int len header_len payload_len; if (len MAX_BUFFER_SIZE) { return -EINVAL; } unsigned char *buf kmalloc(len, GFP_KERNEL);致命点攻击者可以从用户态构造一个极大的payload_len例如0xFFFFFFF0。当它与header_len相加时结果发生了整数回绕变成了一个极小的正数如15。这个小数字顺利通过了MAX_BUFFER_SIZE的检查导致kmalloc只分配了一个极小的内存块。2. 连锁反应堆溢出与 Panic接下来的memcpy或copy_from_user依然会按照原始巨大的payload_len进行拷贝。结果就是小小的缓冲区被瞬间撑破相邻的内核对象被恶意覆盖。攻击者借此可以篡改函数指针甚至直接获取 Root 权限。3. 华为的解决方案华为工程师与社区协作迅速推动了补丁。核心逻辑是引入了内核安全算术库强制校验严禁直接使用或*计算内存大小。引入check_add_overflow使用编译器内置的溢出检测机制在加法发生的瞬间捕捉异常。代码审计华为内部以此为契机对网络协议栈中所有涉及size计算的逻辑进行了地毯式扫描。二、 举一反三这些整数风险你避开了吗除了华为遇到的缓冲区分配问题整数溢出在内核中还有以下变种参考计数溢出Reference Count Overflow当一个内核对象的引用计数refcount被非法增加到溢出并回绕至 0 时内核会误认为该对象已不再使用并将其释放Free。然而系统中可能仍有指针指向它这就造成了Use-After-Free (UAF)漏洞这是目前内核中最易被利用的漏洞类型。循环计数器陷阱for (i 0; i count; i) { ... }如果count来自用户态且由于溢出变成了一个负数对于有符号整型循环可能完全不执行或者如果i溢出导致条件永远为真则会引发内核死循环导致 CPU 100% 占用系统瞬间宕机。数组索引越界计算数组下标时发生溢出可能导致指针访问到数组边界之外的地址。即便溢出后的偏移量很小也可能修改到内核的关键全局变量。三、 社区大地震Kees Cook 与 Linus 的“生死战”面对这些层出不穷的漏洞安全专家 Kees Cook 提出了他的“终极武器”属性标注系统。__ob_wrap官方认证的“回绕”。告诉工具我知道这里会溢出我是故意的比如哈希算法。__ob_trap一旦溢出直接让 CPU 报错停止运行。Linus 的怒火死掉的机器不是安全的Linus Torvalds 对此大发雷霆。他的观点非常务实“一个直接崩溃Oops的系统对用户来说和被黑了同样糟糕。”Linus 认为安全不应该以“自杀”为代价。他提出如果发生了溢出系统应该优雅地跳出当前逻辑清理现场然后报错返回而不是简单粗暴地让整个内核崩掉。四、 最终共识带标签的跳转机制在 Linus 的坚持下社区达成了一个折中且精妙的方案“溢出标签跳转”。int __overflow_label(out_of_bounds) process_data(u32 a, u32 b) { // 标注 count 为“陷阱类型” u32 __attribute__((overflow_behavior(trap))) count; // 执行逻辑 count a b; // 如果这里溢出自动跳转到 out_of_bounds return 0; out_of_bounds: // 优雅清理资源并报错Linus 觉得这很 Cool pr_err(Detect integer overflow! Recovering...\n); return -ERANGE; }五、 结语从华为的补丁实战到内核社区的架构之争我们看到 Linux 内核正在从“防御 Bug”向“改变语言规范”演进。作为内核开发者或底层驱动开发者我们要记住数学不会骗人但 C 语言会。永远不要相信用户输入的长度永远优先使用check_add_overflow和array_size等安全宏。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2583241.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!