Re: [PATCH] fs/namespace: fix NULL pointer dereference in do_lock_mount()
From: Vineet Agarwal
Date: Wed May 06 2026 - 00:38:01 EST
Hi,
Thanks for the follow-up.
I don’t have a stable reproducer yet; the issue is triggered by syzkaller
under fuzzing on a local build (7.1.0-rc1 with KASAN enabled).
However, I was able to capture consistent KASAN reports. The issue is not
limited to a NULL dereference — I am also observing slab-use-after-free
in do_lock_mount().
From the reports, the accessed object belongs to mnt_cache, and is freed
via mntput_no_expire_slowpath() from a concurrent umount path, while
do_lock_mount() is still using the mount returned by where_to_mount().
The stack traces consistently follow this pattern:
do_lock_mount()
→ where_to_mount()
→ do_move_mount()
→ __do_sys_move_mount()
with the freeing happening via:
mntput_no_expire_slowpath()
→ path_umount()
→ __x64_sys_umount()
This seems consistent with a race between move_mount and umount, where
the mount object returned by where_to_mount() is no longer valid after
dropping mount_locked_reader.
I agree that my earlier explanation focusing on dentry state was not
accurate. The issue appears to be related to mount lifetime rather than
dentry revalidation.
Below is one of the stack traces:
==================================================================
BUG: KASAN: slab-use-after-free in topmost_overmount fs/mount.h:239 [inline]
BUG: KASAN: slab-use-after-free in where_to_mount fs/namespace.c:2695 [inline]
BUG: KASAN: slab-use-after-free in where_to_mount fs/namespace.c:2688 [inline]
BUG: KASAN: slab-use-after-free in do_lock_mount.part.0+0xa1b/0xbf0 fs/namespace.c:2756
Call Trace:
<TASK>
topmost_overmount fs/mount.h:239 [inline]
where_to_mount fs/namespace.c:2695 [inline]
where_to_mount fs/namespace.c:2688 [inline]
do_lock_mount.part.0+0xa1b/0xbf0 fs/namespace.c:2756
do_lock_mount fs/namespace.c:2751 [inline]
do_move_mount.isra.0+0x1ac/0xce0 fs/namespace.c:3645
vfs_move_mount fs/namespace.c:4561 [inline]
__do_sys_move_mount+0x62e/0x770 fs/namespace.c:4629
do_syscall_64+0xe0/0x5a0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
Allocated by task:
alloc_vfsmnt fs/namespace.c:287
vfs_create_mount fs/namespace.c:1171
fc_mount fs/namespace.c:1191
do_new_mount fs/namespace.c:3840
path_mount fs/namespace.c:4160
__x64_sys_mount fs/namespace.c:4366
Freed by task:
mntput_no_expire_slowpath fs/namespace.c:1379
path_umount fs/namespace.c:2046
__x64_sys_umount fs/namespace.c:2068
==================================================================
Regarding the earlier patch, the added checks do not reliably trigger
under this workload, which suggests that they are not addressing the
actual root cause.
I’m now investigating the lifetime guarantees around the mount returned
by where_to_mount() and whether additional synchronization or
revalidation is required.
Also, the .config used for testing is attached.
Thanks,
Vineet
On Wed, May 06, 2026 at 03:12:30AM +0100, Al Viro wrote:
> Do you have a reproducer? Which kernel it is and what .config is used?
> Incidentally, do the checks in your patch actually trigger on the setup
> you are testing?
While we are at it, could you post the stack traces of these oopsen?
Attachment:
kernel.config
Description: Binary data