summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-11-29 13:34:59 +0000
committerkib <kib@FreeBSD.org>2008-11-29 13:34:59 +0000
commitbf74bb2e167fcc7089b250309aa7131a27b672e2 (patch)
tree74a7c36a02638c961fd484be28f826c1acdb6a3a /sys/kern/vfs_subr.c
parent881f5f6bef889a5fc9f878e367245de363a1c55e (diff)
downloadFreeBSD-src-bf74bb2e167fcc7089b250309aa7131a27b672e2.zip
FreeBSD-src-bf74bb2e167fcc7089b250309aa7131a27b672e2.tar.gz
In the nfsrv_fhtovp(), after the vfs_getvfs() function found the pointer
to the fs, but before a vnode on the fs is locked, unmount may free fs structures, causing access to destroyed data and freed memory. Introduce a vfs_busymp() function that looks up and busies found fs while mountlist_mtx is held. Use it in nfsrv_fhtovp() and in the implementation of the handle syscalls. Two other uses of the vfs_getvfs() in the vfs_subr.c, namely in sysctl_vfs_ctl and vfs_getnewfsid seems to be ok. In particular, sysctl_vfs_ctl is protected by Giant by being a non-sleeping sysctl handler, that prevents Giant-locked unmount code to interfere with it. Noted by: tegge Reviewed by: dfr Tested by: pho MFC after: 1 month
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 32093c0..16373b1 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -407,6 +407,32 @@ vfs_getvfs(fsid_t *fsid)
}
/*
+ * Lookup a mount point by filesystem identifier, busying it before
+ * returning.
+ */
+struct mount *
+vfs_busyfs(fsid_t *fsid)
+{
+ struct mount *mp;
+ int error;
+
+ mtx_lock(&mountlist_mtx);
+ TAILQ_FOREACH(mp, &mountlist, mnt_list) {
+ if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
+ mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) {
+ error = vfs_busy(mp, MBF_MNTLSTLOCK);
+ if (error) {
+ mtx_unlock(&mountlist_mtx);
+ return (NULL);
+ }
+ return (mp);
+ }
+ }
+ mtx_unlock(&mountlist_mtx);
+ return ((struct mount *) 0);
+}
+
+/*
* Check if a user can access privileged mount options.
*/
int
OpenPOWER on IntegriCloud