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>
diff --git a/fs/namespace.c b/fs/namespace.c
index c2340e8..ba90c5d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1691,6 +1691,12 @@
 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)
@@ -1707,12 +1713,6 @@
 		/* 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;
 }