正常
导引:三块凑合要换掉
三块各自的 punchline:
vfs_lookup让execve("/sbin/init")能 follow 符号链接找到真正的 busybox;引用计数让 pipe 的dup不再误发 EOF、让缓存返回的指针不会突然失效;ext2 inode 缓存改成堆 + refcount 后,那个「ASAN 都看不见的静默别名 UAF」从结构上没了。
这章咱们要点亮什么
- 路径解析 ≠ 字符串规范化:
/a/b/c要真的从根 inode 出发,一层层lookup_child拿到a、b、c的 inode。./..是字符串层面能压,但符号链接必须「读出目标、拼回去、重新解析」——这是字符串干不了的。 - inode 得有引用计数,而且 release 要在「最后一个引用」时才发:多个 fd(dup/fork)指向同一个 inode,关一个 fd 不能就发 EOF/拆连接——得等最后一个关。这要外层 inode 引用计数 + 锁外 release。
- 缓存返回的对象必须 pin 住(引用计数 > 0),不能返回一个「随时可能被驱逐覆盖」的指针。否则调用方拿着指针,缓存转身把那块内存给了别的 inode,调用方就读到错的数据——而且是静默错,工具看不见。
- 环检测靠深度计数封顶:符号链接可以互相指(
a→b→a),follow 时得有一个「最多跟 40 层」的上限,否则死循环。