[PATCH 02/10] vfs: syscall: Add move_mount(2) to move mounts around
Jann Horn
jannh at google.com
Wed Feb 20 16:23:46 UTC 2019
On Tue, Feb 19, 2019 at 6:08 PM David Howells <dhowells at redhat.com> wrote:
> Add a move_mount() system call that will move a mount from one place to
> another and, in the next commit, allow to attach an unattached mount tree.
>
> The new system call looks like the following:
>
> int move_mount(int from_dfd, const char *from_path,
> int to_dfd, const char *to_path,
> unsigned int flags);
>
> Signed-off-by: David Howells <dhowells at redhat.com>
> cc: linux-api at vger.kernel.org
> Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
> ---
[...]
> +/*
> + * Move a mount from one place to another.
> + *
> + * Note the flags value is a combination of MOVE_MOUNT_* flags.
> + */
> +SYSCALL_DEFINE5(move_mount,
> + int, from_dfd, const char *, from_pathname,
> + int, to_dfd, const char *, to_pathname,
> + unsigned int, flags)
> +{
> + struct path from_path, to_path;
> + unsigned int lflags;
> + int ret = 0;
> +
> + if (!may_mount())
> + return -EPERM;
> +
> + if (flags & ~MOVE_MOUNT__MASK)
> + return -EINVAL;
> +
> + /* If someone gives a pathname, they aren't permitted to move
> + * from an fd that requires unmount as we can't get at the flag
> + * to clear it afterwards.
> + */
> + lflags = 0;
> + if (flags & MOVE_MOUNT_F_SYMLINKS) lflags |= LOOKUP_FOLLOW;
> + if (flags & MOVE_MOUNT_F_AUTOMOUNTS) lflags |= LOOKUP_AUTOMOUNT;
> + if (flags & MOVE_MOUNT_F_EMPTY_PATH) lflags |= LOOKUP_EMPTY;
> +
> + ret = user_path_at(from_dfd, from_pathname, lflags, &from_path);
> + if (ret < 0)
> + return ret;
> +
> + lflags = 0;
> + if (flags & MOVE_MOUNT_T_SYMLINKS) lflags |= LOOKUP_FOLLOW;
> + if (flags & MOVE_MOUNT_T_AUTOMOUNTS) lflags |= LOOKUP_AUTOMOUNT;
> + if (flags & MOVE_MOUNT_T_EMPTY_PATH) lflags |= LOOKUP_EMPTY;
> +
> + ret = user_path_at(to_dfd, to_pathname, lflags, &to_path);
> + if (ret < 0)
> + goto out_from;
> +
> + ret = security_move_mount(&from_path, &to_path);
> + if (ret < 0)
> + goto out_to;
Wouldn't you want to call this from do_move_mount() instead for
consistency? If MS_MOVE and this thing perform the same logical
operation, they should probably also call the same LSM hook.
> + ret = do_move_mount(&from_path, &to_path);
> +
> +out_to:
> + path_put(&to_path);
> +out_from:
> + path_put(&from_path);
> + return ret;
> +}
[...]
> diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h
> index fd7ae2e7eccf..3634e065836c 100644
> --- a/include/uapi/linux/mount.h
> +++ b/include/uapi/linux/mount.h
> @@ -61,4 +61,15 @@
> #define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */
> #define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */
>
> +/*
> + * move_mount() flags.
> + */
> +#define MOVE_MOUNT_F_SYMLINKS 0x00000001 /* Follow symlinks on from path */
"Follow symlinks" sounds a bit misleading. LOOKUP_NOFOLLOW only
applies to the last element of the path; and there is a pending
patchset that's going to let userspace ask the kernel to actually not
follow *any* symlinks on the path with O_NOSYMLINKS, so this might
confuse people. Maybe change the comment to "don't follow trailing
symlink", or something like that?
More information about the Linux-security-module-archive
mailing list