Bug 255047 - race bug with mount generating same fsid for different mount points
Summary: race bug with mount generating same fsid for different mount points
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-04-14 09:14 UTC by Olivier Cochard
Modified: 2022-11-06 21:28 UTC (History)
2 users (show)

See Also:


Attachments
script to reproduce the bug (1.37 KB, text/plain)
2021-04-14 09:14 UTC, Olivier Cochard
no flags Details
script to reproduce the bug (1.76 KB, text/plain)
2022-11-04 21:26 UTC, Olivier Cochard
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Cochard freebsd_committer freebsd_triage 2021-04-14 09:14:45 UTC
Created attachment 224098 [details]
script to reproduce the bug

Here is a small shell script to reproduce a race bug with mount/umount.

A beginning of explanation by Chuck Silvers:
"the umount command prefers to tell the kernel which fs to unmount not by the path that it is given on the command line, but rather by fsid, which it gets from the getfsstat() syscall.
There is code in the kernel mount syscall that is supposed to detect this and generate an unique, ephemeral fsid if an ffs file system being mounted has the same fsid on disk as another file system that is already mounted, but that code has a race that can cause it to miss detecting the duplicate fsid if the two mounts of file systems with the same on-disk fsid happen at the same time."  


Once started this shell script should display this kind of output:

# ./bug.sh
Initializing...
Creating one 500MB file...
Creating md device to newfs it (mkimage ??)...
newfs it...
/dev/md0: 500.0MB (1024000 sectors) block size 32768, fragment size 4096
        using 4 cylinder groups of 125.03MB, 4001 blks, 16128 inodes.
super-block backups (for fsck_ffs -b #) at:
 192, 256256, 512320, 768384
Destroying md device md0...
Ready to trigger bug!
[2] Copying /tmp/mount_bug into /tmp/2...
[1] Copying /tmp/mount_bug into /tmp/1...
[1] Creating md device...
[1] mount md0 into /tmp/1.mnt...
[2] Creating md device...
[2] mount md1 into /tmp/2.mnt...
[1] fsid of the mount point /tmp/1.mnt/: superblock location    65536   id      [ 6076b0bb 46c244a6 ]
[1] Creating a file into it /tmp/1.mnt/...
[2] fsid of the mount point /tmp/2.mnt/: superblock location    65536   id      [ 6076b0bb 46c244a6 ]
[2] Creating a file into it /tmp/2.mnt/...
[1] unmount /tmp/1.mnt...
umount: unmount of /tmp/1.mnt failed: Device busy
[2] unmount /tmp/2.mnt...
umount failed because: 1) it umounted the wrong (still creating file) or 2) already unmount by the other!
[1] Destroying md device md0...
mdconfig: ioctl(/dev/mdctl): Device busy
destroying md device failed, because still mounted
[1] cleaning up...
[2] Destroying md device md1...
[2] cleaning up...
rm: /tmp/1.mnt: Device busy
Comment 1 Olivier Cochard freebsd_committer freebsd_triage 2022-11-04 21:26:48 UTC
Created attachment 237865 [details]
script to reproduce the bug
Comment 2 Olivier Cochard freebsd_committer freebsd_triage 2022-11-06 21:28:59 UTC
Source of the problem in vfs_getnewfsid() in sys/kern/vfs_subr.c that has this comment:

  * Keep in mind that several mounts may be running in parallel.  Starting
  * the search one past where the previous search terminated is both a
  * micro-optimization and a defense against returning the same fsid to
  * different mounts.


This protection doesn't work here.