一个藏了四十年的内核 bug:UNIX 域套接字的 inode
来源: yuvalino.com — 2026-09-05
概述
作者在 DEFCON 34 讲 iOS 沙箱逃逸时,demo 每次开机后第一次运行都会崩溃,且只在首次复现。他排查到自己用一对 UNIX 域套接字在用户态实现 TTY 的代码,一个 inode 号本不该变化却变了。打开 XNU 源码后答案浮现:uipc_sense() 里第一次给套接字分配 inode 用的是 unp_ino++,而为 0 的全局变量让系统上第一颗被 fstat 的套接字拿到 inode 0,随后又被当作「未初始化」重新分配。顺着历史回溯,这个写法在 2001 年的 XNU 123.5,以及更早的 4.3BSD-Tahoe 里一字未改,最后一次修改是 1985 年 12 月;再往前一次提交的说明写着「为天真的人伪造 inode 号和 dev」——那一年,大概正是有人第一次在天真地用 fstat 检查套接字。
核心要点
- 崩溃根源是一行自增方向:应为 ++unp_ino 却写成 unp_ino++,于是系统首颗被 fstat 的套接字拿到 inode 0,被判为「未初始化」后二次分配。
- 问题不是内存损坏,因此它跳过 ASLR 与竞态,只在重启之后的第一次调用上确定性复现。
- 这条代码在 2001 年的 XNU 123.5 与 4.3BSD-Tahoe 中几乎一字未改,最后一次变更停留在 1985 年 12 月 20 日。
- 1985 年那次提交的说明写着「为天真的人伪造 inode 号和 dev」,作者调侃自己被一条四十一年前的提交信息称为天真。
金句
上舞台之前,把 demo 验证得更仔细一点。
👍 0
👎 0
返回 Lobsters 首页