summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-05-27 09:22:50 +0000
committerkib <kib@FreeBSD.org>2015-05-27 09:22:50 +0000
commitd77dbf3761f318998d4f01063cea23ad73dc7bdf (patch)
tree94255445469c1443152fced77eb57ef614568b66 /sys/kern/vfs_subr.c
parent260b7bb2591a59fccbee5832cc083c39d7cf2bba (diff)
downloadFreeBSD-src-d77dbf3761f318998d4f01063cea23ad73dc7bdf.zip
FreeBSD-src-d77dbf3761f318998d4f01063cea23ad73dc7bdf.tar.gz
Right now, dounmount() is called with unreferenced mount point.
Nothing stops a parallel unmount to suceed before the given call to dounmount() checks and locks the covered vnode. Prevent dounmount() from acting on the freed (although type-stable) memory by changing the interface to require the mount point to be referenced. dounmount() consumes the reference on return, regardless of the sucessfull or erronous result. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 8e34456..625d193 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -3502,8 +3502,9 @@ vfs_unmountall(void)
*/
while(!TAILQ_EMPTY(&mountlist)) {
mp = TAILQ_LAST(&mountlist, mntlist);
+ vfs_ref(mp);
error = dounmount(mp, MNT_FORCE, td);
- if (error) {
+ if (error != 0) {
TAILQ_REMOVE(&mountlist, mp, mnt_list);
/*
* XXX: Due to the way in which we mount the root
OpenPOWER on IntegriCloud