Skip to content

Commit 25d202e

Browse files
committed
mount: Retest MNT_LOCKED in do_umount
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>
1 parent d2f007d commit 25d202e

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

fs/namespace.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,8 +1540,13 @@ static int do_umount(struct mount *mnt, int flags)
15401540

15411541
namespace_lock();
15421542
lock_mount_hash();
1543-
event++;
15441543

1544+
/* Recheck MNT_LOCKED with the locks held */
1545+
retval = -EINVAL;
1546+
if (mnt->mnt.mnt_flags & MNT_LOCKED)
1547+
goto out;
1548+
1549+
event++;
15451550
if (flags & MNT_DETACH) {
15461551
if (!list_empty(&mnt->mnt_list))
15471552
umount_tree(mnt, UMOUNT_PROPAGATE);
@@ -1555,6 +1560,7 @@ static int do_umount(struct mount *mnt, int flags)
15551560
retval = 0;
15561561
}
15571562
}
1563+
out:
15581564
unlock_mount_hash();
15591565
namespace_unlock();
15601566
return retval;
@@ -1645,7 +1651,7 @@ int ksys_umount(char __user *name, int flags)
16451651
goto dput_and_out;
16461652
if (!check_mnt(mnt))
16471653
goto dput_and_out;
1648-
if (mnt->mnt.mnt_flags & MNT_LOCKED)
1654+
if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
16491655
goto dput_and_out;
16501656
retval = -EPERM;
16511657
if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))

0 commit comments

Comments
 (0)