⬢ DragonFlyBSD Kernel Audit
DF-3250 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/ext2fs/ext2_vfsops.c	2026-06-29 12:51:19.000000000 +0000
+++ fixedtree/sys/vfs/ext2fs/ext2_vfsops.c	2026-09-09 13:27:28.257294986 +0000
@@ -1294,7 +1294,6 @@
 		return (error);
 	}
 	//lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
-	vp->v_data = ip;
 	ip->i_vnode = vp;
 	ip->i_e2fs = ump->um_e2fs;
 	ip->i_dev = ump->um_dev;
@@ -1319,6 +1318,16 @@
 		free(ip, M_EXT2NODE);
 		return (-1);
 	}
+	/*
+	 * Publish v_data only after a successful hash insert.  On the EBUSY
+	 * path above the vnode is discarded via vx_put(); the synchronous
+	 * VREF_FINALIZE reclaim in vx_put() runs ext2_reclaim(), which must
+	 * see v_data == NULL so it neither walks nor frees the inode that
+	 * we free above ourselves (otherwise the inode is double-freed and
+	 * um_devvp is vrele'd without a matching vref).  Mirrors the
+	 * ffs_vget() ordering (ffs_vfsops.c:1120-1129).
+	 */
+	vp->v_data = ip;
 
 	if (ext2fs_inode_hash_lock < 0)
 		wakeup(&ext2fs_inode_hash_lock);