diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-03-23 15:05:07 +0100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-04-14 09:30:15 +0200 |
| commit | ad4999496e73923adb524b24c2f448c9498476b5 (patch) | |
| tree | 0b6c8e08a7c7d1c9b611d629eff35bce471f85c2 /rust/kernel/ptr/git@git.tavy.me:linux.git | |
| parent | 43dcce3f2a6209898f31d1ef99e0a4a1335ebb67 (diff) | |
mount: always duplicate mount
In the OPEN_TREE_NAMESPACE path vfs_open_tree() resolves a path via
filename_lookup() without holding namespace_lock. Between the lookup
and create_new_namespace() acquiring namespace_lock via
LOCK_MOUNT_EXACT_COPY() another thread can unmount the mount, setting
mnt->mnt_ns to NULL.
When create_new_namespace() then checks !mnt->mnt_ns it incorrectly
takes the swap-and-mntget path that was designed for fsmount()'s
detached mounts. This reuses a mount whose mnt_mp_list is in an
inconsistent state from the concurrent unmount, causing a general
protection fault in __umount_mnt() -> hlist_del_init(&mnt->mnt_mp_list)
during namespace teardown.
Remove the !mnt->mnt_ns special case entirely. Instead, always
duplicate the mount:
- For OPEN_TREE_NAMESPACE use __do_loopback() which will properly
clone the mount or reject it via may_copy_tree() if it was
unmounted in the race window.
- For fsmount() use clone_mnt() directly (via the new MOUNT_COPY_NEW
flag) since the mount is freshly created by vfs_create_mount() and
not in any namespace so __do_loopback()'s IS_MNT_UNBINDABLE,
may_copy_tree, and __has_locked_children checks don't apply.
Reported-by: syzbot+e4470cc28308f2081ec8@syzkaller.appspotmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'rust/kernel/ptr/git@git.tavy.me:linux.git')
0 files changed, 0 insertions, 0 deletions
