Skip to content

Commit

Permalink
mount: Retest MNT_LOCKED in do_umount
Browse files Browse the repository at this point in the history
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: Al Viro <viro@ZenIV.linux.org.uk>
Fixes: 5ff9d8a ("vfs: Lock in place mounts from more privileged users")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
  • Loading branch information
Eric W. Biederman committed Nov 8, 2018
1 parent d2f007d commit 25d202e
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1540,8 +1540,13 @@ static int do_umount(struct mount *mnt, int flags)

namespace_lock();
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 (!list_empty(&mnt->mnt_list))
umount_tree(mnt, UMOUNT_PROPAGATE);
Expand All @@ -1555,6 +1560,7 @@ static int do_umount(struct mount *mnt, int flags)
retval = 0;
}
}
out:
unlock_mount_hash();
namespace_unlock();
return retval;
Expand Down Expand Up @@ -1645,7 +1651,7 @@ int ksys_umount(char __user *name, int flags)
goto dput_and_out;
if (!check_mnt(mnt))
goto dput_and_out;
if (mnt->mnt.mnt_flags & MNT_LOCKED)
if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
goto dput_and_out;
retval = -EPERM;
if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
Expand Down

0 comments on commit 25d202e

Please sign in to comment.