fs: namespace: Fix use-after-free in unmount

During unmount, there is a chance that mntput_no_expire()
scheduled delayed_mntput_work() or in case MNT_INTERNAL
flag is set it can directly call cleanup_mnt().
This results in use-after-free in umount_end check as
mnt is already freed via below path :
cleanup_mnt()->delayed_free_mnt()->free_vfsmnt().

Fix this by moving unmount_end() before mntput_no_expire.

Change-Id: Ib3468ca3b1b3c137484b70972db5d5569f2f2753
Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
Signed-off-by: UtsavBalar1231 <utsavbalar1231@gmail.com>
This commit is contained in:
Sayali Lokhande
2020-01-09 14:45:19 +05:30
committed by UtsavBalar1231
parent e07b3b9b06
commit 91d86541c6

View File

@@ -1778,6 +1778,12 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
dput_and_out:
/* we mustn't call path_put() as that would clear mnt_expiry_mark */
dput(path.dentry);
if (user_request && (!retval || (flags & MNT_FORCE))) {
/* filesystem needs to handle unclosed namespaces */
if (mnt->mnt.mnt_sb->s_op->umount_end)
mnt->mnt.mnt_sb->s_op->umount_end(mnt->mnt.mnt_sb,
flags);
}
mntput_no_expire(mnt);
if (!user_request)
@@ -1794,11 +1800,6 @@ dput_and_out:
/* flush delayed_mntput_work to put sb->s_active */
flush_delayed_mntput_wait();
}
if (!retval || (flags & MNT_FORCE)) {
/* filesystem needs to handle unclosed namespaces */
if (mnt->mnt.mnt_sb->s_op->umount_end)
mnt->mnt.mnt_sb->s_op->umount_end(mnt->mnt.mnt_sb, flags);
}
out:
return retval;
}