finish_automount(): don't leak MNT_LOCKED from parent to child
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 4 May 2025 17:28:37 +0000 (13:28 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 7 Jun 2025 04:40:25 +0000 (00:40 -0400)
Intention for MNT_LOCKED had always been to protect the internal
mountpoints within a subtree that got copied across the userns boundary,
not the mountpoint that tree got attached to - after all, it _was_
exposed before the copying.

For roots of secondary copies that is enforced in attach_recursive_mnt() -
MNT_LOCKED is explicitly stripped for those.  For the root of primary
copy we are almost always guaranteed that MNT_LOCKED won't be there,
so attach_recursive_mnt() doesn't bother.  Unfortunately, one call
chain got overlooked - triggering e.g. NFS referral will have the
submount inherit the public flags from parent; that's fine for such
things as read-only, nosuid, etc., but not for MNT_LOCKED.

This is particularly pointless since the mount attached by finish_automount()
is usually expirable, which makes any protection granted by MNT_LOCKED
null and void; just wait for a while and that mount will go away on its own.

Include MNT_LOCKED into the set of flags to be ignored by do_add_mount() - it
really is an internal flag.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
include/linux/mount.h

index 6904ad33ee7a32759259ac83a9ace3e4b5154884..1a3136e53eaa07b9c256a775966a15983c2ebe33 100644 (file)
@@ -65,7 +65,8 @@ enum mount_flags {
        MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
 
        MNT_INTERNAL_FLAGS = MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL |
-                            MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED,
+                            MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED |
+                            MNT_LOCKED,
 };
 
 struct vfsmount {