]> www.infradead.org Git - users/hch/misc.git/commitdiff
mount: ensure we don't pointlessly walk the mount tree
authorChristian Brauner <brauner@kernel.org>
Wed, 9 Apr 2025 08:00:23 +0000 (10:00 +0200)
committerChristian Brauner <brauner@kernel.org>
Fri, 11 Apr 2025 13:24:29 +0000 (15:24 +0200)
This logic got broken recently. Add it back.

Fixes: 474f7825d533 ("fs: add copy_mount_setattr() helper")
Link: https://lore.kernel.org/20250409-sektflaschen-gecko-27c021fbd222@brauner
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/namespace.c

index 14935a0500a2068e08bb8a53787b1d6e404e474f..1eb76d6312de51656a2d34ca6cb9bcec4bc3e935 100644 (file)
@@ -5189,8 +5189,8 @@ static void finish_mount_kattr(struct mount_kattr *kattr)
                mnt_idmap_put(kattr->mnt_idmap);
 }
 
-static int copy_mount_setattr(struct mount_attr __user *uattr, size_t usize,
-                             struct mount_kattr *kattr)
+static int wants_mount_setattr(struct mount_attr __user *uattr, size_t usize,
+                              struct mount_kattr *kattr)
 {
        int ret;
        struct mount_attr attr;
@@ -5213,9 +5213,13 @@ static int copy_mount_setattr(struct mount_attr __user *uattr, size_t usize,
        if (attr.attr_set == 0 &&
            attr.attr_clr == 0 &&
            attr.propagation == 0)
-               return 0;
+               return 0; /* Tell caller to not bother. */
+
+       ret = build_mount_kattr(&attr, usize, kattr);
+       if (ret < 0)
+               return ret;
 
-       return build_mount_kattr(&attr, usize, kattr);
+       return 1;
 }
 
 SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path,
@@ -5247,8 +5251,8 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path,
        if (flags & AT_RECURSIVE)
                kattr.kflags |= MOUNT_KATTR_RECURSE;
 
-       err = copy_mount_setattr(uattr, usize, &kattr);
-       if (err)
+       err = wants_mount_setattr(uattr, usize, &kattr);
+       if (err <= 0)
                return err;
 
        err = user_path_at(dfd, path, kattr.lookup_flags, &target);
@@ -5282,15 +5286,17 @@ SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename,
                if (flags & AT_RECURSIVE)
                        kattr.kflags |= MOUNT_KATTR_RECURSE;
 
-               ret = copy_mount_setattr(uattr, usize, &kattr);
-               if (ret)
+               ret = wants_mount_setattr(uattr, usize, &kattr);
+               if (ret < 0)
                        return ret;
 
-               ret = do_mount_setattr(&file->f_path, &kattr);
-               if (ret)
-                       return ret;
+               if (ret) {
+                       ret = do_mount_setattr(&file->f_path, &kattr);
+                       if (ret)
+                               return ret;
 
-               finish_mount_kattr(&kattr);
+                       finish_mount_kattr(&kattr);
+               }
        }
 
        fd = get_unused_fd_flags(flags & O_CLOEXEC);