Commit 5e64ee87 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Greg Kroah-Hartman
Browse files

mount: Retest MNT_LOCKED in do_umount

commit 25d202ed

 upstream.

It was recently pointed out that the one instance of testing MNT_LOCKED
outside of the namespace_sem is in ksys_umount.

Fix that by adding a test inside of do_umount with namespace_sem and
the mount_lock held.  As it helps to fail fails the existing test is
maintained with an additional comment pointing out that it may be racy
because the locks are not held.

Cc: stable@vger.kernel.org
Reported-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
Fixes: 5ff9d8a6

 ("vfs: Lock in place mounts from more privileged users")
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 68b90875
...@@ -1625,8 +1625,13 @@ static int do_umount(struct mount *mnt, int flags) ...@@ -1625,8 +1625,13 @@ static int do_umount(struct mount *mnt, int flags)
namespace_lock(); namespace_lock();
lock_mount_hash(); lock_mount_hash();
event++;
/* Recheck MNT_LOCKED with the locks held */
retval = -EINVAL;
if (mnt->mnt.mnt_flags & MNT_LOCKED)
goto out;
event++;
if (flags & MNT_DETACH) { if (flags & MNT_DETACH) {
if (!list_empty(&mnt->mnt_list)) if (!list_empty(&mnt->mnt_list))
umount_tree(mnt, UMOUNT_PROPAGATE); umount_tree(mnt, UMOUNT_PROPAGATE);
...@@ -1640,6 +1645,7 @@ static int do_umount(struct mount *mnt, int flags) ...@@ -1640,6 +1645,7 @@ static int do_umount(struct mount *mnt, int flags)
retval = 0; retval = 0;
} }
} }
out:
unlock_mount_hash(); unlock_mount_hash();
namespace_unlock(); namespace_unlock();
return retval; return retval;
...@@ -1730,7 +1736,7 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) ...@@ -1730,7 +1736,7 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
goto dput_and_out; goto dput_and_out;
if (!check_mnt(mnt)) if (!check_mnt(mnt))
goto dput_and_out; goto dput_and_out;
if (mnt->mnt.mnt_flags & MNT_LOCKED) if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
goto dput_and_out; goto dput_and_out;
retval = -EPERM; retval = -EPERM;
if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment