diff options
-rw-r--r-- | fs/namespace.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 98d27da43304..72f10c40fe3f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1540,8 +1540,13 @@ static int do_umount(struct mount *mnt, int flags) | |||
1540 | 1540 | ||
1541 | namespace_lock(); | 1541 | namespace_lock(); |
1542 | lock_mount_hash(); | 1542 | lock_mount_hash(); |
1543 | event++; | ||
1544 | 1543 | ||
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++; | ||
1545 | if (flags & MNT_DETACH) { | 1550 | if (flags & MNT_DETACH) { |
1546 | if (!list_empty(&mnt->mnt_list)) | 1551 | if (!list_empty(&mnt->mnt_list)) |
1547 | umount_tree(mnt, UMOUNT_PROPAGATE); | 1552 | umount_tree(mnt, UMOUNT_PROPAGATE); |
@@ -1555,6 +1560,7 @@ static int do_umount(struct mount *mnt, int flags) | |||
1555 | retval = 0; | 1560 | retval = 0; |
1556 | } | 1561 | } |
1557 | } | 1562 | } |
1563 | out: | ||
1558 | unlock_mount_hash(); | 1564 | unlock_mount_hash(); |
1559 | namespace_unlock(); | 1565 | namespace_unlock(); |
1560 | return retval; | 1566 | return retval; |
@@ -1645,7 +1651,7 @@ int ksys_umount(char __user *name, int flags) | |||
1645 | goto dput_and_out; | 1651 | goto dput_and_out; |
1646 | if (!check_mnt(mnt)) | 1652 | if (!check_mnt(mnt)) |
1647 | goto dput_and_out; | 1653 | goto dput_and_out; |
1648 | if (mnt->mnt.mnt_flags & MNT_LOCKED) | 1654 | if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ |
1649 | goto dput_and_out; | 1655 | goto dput_and_out; |
1650 | retval = -EPERM; | 1656 | retval = -EPERM; |
1651 | if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) | 1657 | if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) |