diff options
author | kib <kib@FreeBSD.org> | 2015-05-27 09:22:50 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-05-27 09:22:50 +0000 |
commit | d77dbf3761f318998d4f01063cea23ad73dc7bdf (patch) | |
tree | 94255445469c1443152fced77eb57ef614568b66 /sys/kern/vfs_subr.c | |
parent | 260b7bb2591a59fccbee5832cc083c39d7cf2bba (diff) | |
download | FreeBSD-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.c | 3 |
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 |