Skip to content

Commit

Permalink
vfs: move_mount: reject moving kernel internal mounts
Browse files Browse the repository at this point in the history
sys_move_mount() crashes by dereferencing the pointer MNT_NS_INTERNAL,
a.k.a. ERR_PTR(-EINVAL), if the old mount is specified by fd for a
kernel object with an internal mount, such as a pipe or memfd.

Fix it by checking for this case and returning -EINVAL.

[AV: what we want is is_mounted(); use that instead of making the
condition even more convoluted]

Reproducer:

    #include <unistd.h>

    #define __NR_move_mount         429
    #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004

    int main()
    {
    	int fds[2];

    	pipe(fds);
        syscall(__NR_move_mount, fds[0], "", -1, "/", MOVE_MOUNT_F_EMPTY_PATH);
    }

Reported-by: [email protected]
Fixes: 2db154b ("vfs: syscall: Add move_mount(2) to move mounts around")
Signed-off-by: Eric Biggers <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
ebiggers authored and Al Viro committed Jul 1, 2019
1 parent d728cf7 commit 570d7a9
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2596,11 +2596,12 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
if (!check_mnt(p))
goto out;

/* The thing moved should be either ours or completely unattached. */
if (attached && !check_mnt(old))
/* The thing moved must be mounted... */
if (!is_mounted(&old->mnt))
goto out;

if (!attached && !(ns && is_anon_ns(ns)))
/* ... and either ours or the root of anon namespace */
if (!(attached ? check_mnt(old) : is_anon_ns(ns)))
goto out;

if (old->mnt.mnt_flags & MNT_LOCKED)
Expand Down

0 comments on commit 570d7a9

Please sign in to comment.