CVE-2026-98539 in Linux
摘要
由 VulDB • 2026-10-19
在 Linux 内核中,已修复以下漏洞:
fs/ntfs3: 在 ntfs_create_inode() 中使用 d_instantiate_new(),并终结 syzbot “do_new_mount 中的警告”这一令人头疼的 saga。
ntfs_create_inode() 通过 ntfs_new_inode() 创建一个新的 inode(索引节点)。它使用 insert_inode_locked() 对其进行哈希处理,因此在 unlock_new_inode() 之前被标记为 I_NEW。
然而,ntfs3 在此过程中调用了 d_instantiate()……由于在创建操作之前查找过程已经对该目录项进行了哈希处理,因此任何路径遍历都会找到该目录项,而无需触碰父级的 i_rwsem(读写信号量),从而可以锁定 inode。
如果该 inode 是一个目录,unlock_new_inode() 会调用 lockdep_annotate_inode_mutex_key(),并将 i_rwsem 标记为 i_mutex_dir_key 类。
这会重置锁的计数器和所有者,而其他人可能已经持有了该锁……
syzbot 一直在向我们发送相同的令人抓狂的错误报告:
“do_new_mount 中的警告”
自 2023 年以来一直如此。我再也无法忍受了,于是开始排查问题。据我所知,syzbot 的执行器会 chdir(更改当前工作目录)到一个新挂载的 ntfs3 镜像中,创建一个目录,然后在其上挂载一些伪文件系统。每次 mkdir() 耗时超过 syzbot 等待的时间时,mount() 就会并发运行:
mkdir("./sys") mount(NULL, "./sys", "sysfs") ntfs_create_inode() d_instantiate() user_path_at() 找到目录项 do_lock_mount() inode_lock(inode) namespace_lock() unlock_new_inode() lockdep_annotate_inode_mutex_key() init_rwsem(&inode->i_rwsem) unlock_mount() inode_unlock(inode)
挂载端随后释放了一个根据 rwsem 无人持有的锁:
DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) && ...): count = 0x0, magic = 0xffff888043a854e8, owner = 0x0, curr 0xffff888000244880, list empty WARNING: CPU: 0 PID: 5346 at kernel/locking/rwsem.c:1368 __up_write Call Trace: inode_unlock include/linux/fs.h:877 [inline]
unlock_mount fs/namespace.c:2892 [inline]
do_new_mount_fc fs/namespace.c:3828 [inline]
do_new_mount+0x777/0xa40 fs/namespace.c:3887
在 PREEMPT_RT 上,同样的问题表现为:
DEBUG_LOCKS_WARN_ON(rt_mutex_owner(lock) != current) WARNING: kernel/locking/rtmutex_common.h:193 at rt_mutex_slowunlock
up_write() 导致重置后的计数下溢。随后对该目录的 inode_lock() 将永远无法返回。与 mkdir() 竞争的新目录路径遍历会通过 lookup_slow() 中的 inode_lock_shared() 以相同方式破坏锁。
切换至 d_instantiate_new() 并移除尾部的 unlock_new_inode()。所有错误路径都会在该点之前退出,此时 I_NEW 仍处于设置状态,并继续使用 discard_new_inode()。
愿我们再也看不到这个该死的错误报告。
VulDB is the best source for vulnerability data and more expert information about this specific topic.