From 1b0b9cc8d3793e31b313e6c9685513b08cd883c4 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 12 Jun 2019 11:43:13 -0700 Subject: [PATCH 1/2] vfs: fsmount: add missing mntget() sys_fsmount() needs to take a reference to the new mount when adding it to the anonymous mount namespace. Otherwise the filesystem can be unmounted while it's still in use, as found by syzkaller. Reported-by: Mark Rutland Reported-by: syzbot+99de05d099a170867f22@syzkaller.appspotmail.com Reported-by: syzbot+7008b8b8ba7df475fdc8@syzkaller.appspotmail.com Fixes: 93766fbd2696 ("vfs: syscall: Add fsmount() to create a mount for a superblock") Signed-off-by: Eric Biggers Signed-off-by: Al Viro --- fs/namespace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/namespace.c b/fs/namespace.c index b26778bdc236..5dc137a22d40 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3445,6 +3445,7 @@ SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags, ns->root = mnt; ns->mounts = 1; list_add(&mnt->mnt_list, &ns->list); + mntget(newmount.mnt); /* Attach to an apparent O_PATH fd with a note that we need to unmount * it, not just simply put it. From d728cf79164bb38e9628d15276e636539f857ef1 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 17 Jun 2019 23:22:14 +0200 Subject: [PATCH 2/2] fs/namespace: fix unprivileged mount propagation When propagating mounts across mount namespaces owned by different user namespaces it is not possible anymore to move or umount the mount in the less privileged mount namespace. Here is a reproducer: sudo mount -t tmpfs tmpfs /mnt sudo --make-rshared /mnt # create unprivileged user + mount namespace and preserve propagation unshare -U -m --map-root --propagation=unchanged # now change back to the original mount namespace in another terminal: sudo mkdir /mnt/aaa sudo mount -t tmpfs tmpfs /mnt/aaa # now in the unprivileged user + mount namespace mount --move /mnt/aaa /opt Unfortunately, this is a pretty big deal for userspace since this is e.g. used to inject mounts into running unprivileged containers. So this regression really needs to go away rather quickly. The problem is that a recent change falsely locked the root of the newly added mounts by setting MNT_LOCKED. Fix this by only locking the mounts on copy_mnt_ns() and not when adding a new mount. Fixes: 3bd045cc9c4b ("separate copying and locking mount tree on cross-userns copies") Cc: Linus Torvalds Cc: Al Viro Cc: Tested-by: Christian Brauner Acked-by: Christian Brauner Signed-off-by: "Eric W. Biederman" Signed-off-by: Christian Brauner Signed-off-by: Al Viro --- fs/namespace.c | 1 + fs/pnode.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 5dc137a22d40..7660c2749c96 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2105,6 +2105,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, /* Notice when we are propagating across user namespaces */ if (child->mnt_parent->mnt_ns->user_ns != user_ns) lock_mnt_tree(child); + child->mnt.mnt_flags &= ~MNT_LOCKED; commit_tree(child); } put_mountpoint(smp); diff --git a/fs/pnode.c b/fs/pnode.c index 595857a1883e..49f6d7ff2139 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -261,7 +261,6 @@ static int propagate_one(struct mount *m) child = copy_tree(last_source, last_source->mnt.mnt_root, type); if (IS_ERR(child)) return PTR_ERR(child); - child->mnt.mnt_flags &= ~MNT_LOCKED; mnt_set_mountpoint(m, mp, child); last_dest = m; last_source = child;