Skip to content

Commit cd01027

Browse files
Al Virogregkh
Al Viro
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 3edac29 commit cd01027

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
@@ -747,7 +747,7 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
747747
return 0;
748748
mnt = real_mount(bastard);
749749
mnt_add_count(mnt, 1);
750-
smp_mb(); // see mntput_no_expire()
750+
smp_mb(); // see mntput_no_expire() and do_umount()
751751
if (likely(!read_seqretry(&mount_lock, seq)))
752752
return 0;
753753
if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
@@ -1916,6 +1916,7 @@ static int do_umount(struct mount *mnt, int flags)
19161916
umount_tree(mnt, UMOUNT_PROPAGATE);
19171917
retval = 0;
19181918
} else {
1919+
smp_mb(); // paired with __legitimize_mnt()
19191920
shrink_submounts(mnt);
19201921
retval = -EBUSY;
19211922
if (!propagate_mount_busy(mnt, 2)) {

0 commit comments

Comments
 (0)