Skip to content

Commit 6d63fcb

Browse files
Al Virogregkh
authored andcommitted
do_umount(): add missing barrier before refcount checks in sync case
[ Upstream commit 65781e1 ] do_umount() analogue of the race fixed in 119e1ef "fix __legitimize_mnt()/mntput() race". Here we want to make sure that if __legitimize_mnt() doesn't notice our lock_mount_hash(), we will notice their refcount increment. Harder to hit than mntput_no_expire() one, fortunately, and consequences are milder (sync umount acting like umount -l on a rare race with RCU pathwalk hitting at just the wrong time instead of use-after-free galore mntput_no_expire() counterpart used to be hit). Still a bug... Fixes: 48a066e ("RCU'd vfsmounts") Reviewed-by: Christian Brauner <[email protected]> Signed-off-by: Al Viro <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent c4f78f6 commit 6d63fcb

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

fs/namespace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
778778
return 0;
779779
mnt = real_mount(bastard);
780780
mnt_add_count(mnt, 1);
781-
smp_mb(); // see mntput_no_expire()
781+
smp_mb(); // see mntput_no_expire() and do_umount()
782782
if (likely(!read_seqretry(&mount_lock, seq)))
783783
return 0;
784784
if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
@@ -1956,6 +1956,7 @@ static int do_umount(struct mount *mnt, int flags)
19561956
umount_tree(mnt, UMOUNT_PROPAGATE);
19571957
retval = 0;
19581958
} else {
1959+
smp_mb(); // paired with __legitimize_mnt()
19591960
shrink_submounts(mnt);
19601961
retval = -EBUSY;
19611962
if (!propagate_mount_busy(mnt, 2)) {

0 commit comments

Comments
 (0)