mount: ensure we don't pointlessly walk the mount tree

This logic got broken recently. Add it back.

Fixes: 474f7825d5 ("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>
This commit is contained in:
Christian Brauner 2025-04-09 10:00:23 +02:00
parent b2b4483b5d
commit d43dbf7322
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2

View 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. */
return build_mount_kattr(&attr, usize, kattr);
ret = build_mount_kattr(&attr, usize, kattr);
if (ret < 0)
return ret;
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);