Unverified Commit d43dbf73 authored by Christian Brauner's avatar Christian Brauner
Browse files

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

This logic got broken recently. Add it back.

Fixes: 474f7825 ("fs: add copy_mount_setattr() helper")
Link: https://lore.kernel.org/20250409-sektflaschen-gecko-27c021fbd222@brauner


Tested-by: default avatarMikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent b2b4483b
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -5189,7 +5189,7 @@ 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,
static int wants_mount_setattr(struct mount_attr __user *uattr, size_t usize,
			       struct mount_kattr *kattr)
{
	int ret;
@@ -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,16 +5286,18 @@ 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;

		if (ret) {
			ret = do_mount_setattr(&file->f_path, &kattr);
			if (ret)
				return ret;

			finish_mount_kattr(&kattr);
		}
	}

	fd = get_unused_fd_flags(flags & O_CLOEXEC);
	if (fd < 0)