⬢ DragonFlyBSD Kernel Audit
DF-3219 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/dirfs/dirfs_vfsops.c
+++ b/sys/vfs/dirfs/dirfs_vfsops.c
@@ -231,9 +231,15 @@ dirfs_root(struct mount *mp, struct vnode **vpp)
 	int error;
 
 	dmp = VTOEMO(mp);
 
+	/*
+	 * VFS_ROOT is not serialized by the VFS layer; two concurrent
+	 * path resolutions through the mountpoint would both run the
+	 * lazy init below, leaking one node + host fd and publishing a
+	 * root vnode without VROOT.
+	 */
+	lockmgr(&dmp->dm_lock, LK_EXCLUSIVE);
 	if (dmp->dm_root == NULL) {
 		error = dirfs_alloc_helper(dmp, NULL, ".", &dnp);
 		if (error)
 			return (error);
@@ -265,6 +271,7 @@ dirfs_root(struct mount *mp, struct vnode **vpp)
 	 * vn_lock() as we are already holding it.
 	 */
 	vn_unlock(vp);
 
+	lockmgr(&dmp->dm_lock, LK_RELEASE);
 	*vpp = vp;
 	return (0);
 }