DragonFlyBSD Kernel Audit
DF-2621 / instrument.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_admin.c	2026-08-28 15:24:47.450135496 +0000
+++ b/sys/vfs/hammer2/hammer2_admin.c	2026-08-28 15:25:09.529848981 +0000
@@ -421,7 +421,40 @@
 
 /*
  * A mounted PFS needs Xops threads to support frontend operations.
+ *
+ * DF2621 VERIFICATION INSTRUMENTATION (temporary, in-guest build only).
  */
+static hammer2_pfs_t *df2621_freed_ring[16];
+static int df2621_freed_ridx;
+static int df2621_uaf_reports;
+
+void hammer2_df2621_mark_free(hammer2_pfs_t *pmp);
+void
+hammer2_df2621_mark_free(hammer2_pfs_t *pmp)
+{
+	df2621_freed_ring[df2621_freed_ridx++ & 15] = pmp;
+	kprintf("DF2621: pfsfree kfree pmp=%p\n", pmp);
+}
+
+static void
+df2621_check_freed(hammer2_thread_t *thr, hammer2_pfs_t *pmp)
+{
+	int i;
+
+	if (pmp == NULL || df2621_uaf_reports >= 200)
+		return;
+	for (i = 0; i < 16; ++i) {
+		if (df2621_freed_ring[i] == pmp) {
+			++df2621_uaf_reports;
+			kprintf("DF2621: UAF-WRITE thr=%p clindex=%d "
+				"spin_ex(&pmp->xop_spin) on FREED pmp=%p "
+				"(report %d)\n",
+				thr, thr->clindex, pmp, df2621_uaf_reports);
+			return;
+		}
+	}
+}
+
 void
 hammer2_xop_helper_create(hammer2_pfs_t *pmp)
 {
@@ -431,9 +464,14 @@
 	lockmgr(&pmp->lock, LK_EXCLUSIVE);
 	pmp->has_xop_threads = 1;
 
+	kprintf("DF2621: helper_create pmp=%p old_groups=%p nchains=%d\n",
+		pmp, pmp->xop_groups,
+		pmp->iroot ? pmp->iroot->cluster.nchains : -1);
 	pmp->xop_groups = kmalloc(hammer2_xop_nthreads *
 				  sizeof(hammer2_xop_group_t),
 				  M_HAMMER2, M_WAITOK | M_ZERO);
+	kprintf("DF2621: helper_create pmp=%p new_groups=%p (OLD LEAKED)\n",
+		pmp, pmp->xop_groups);
 	for (i = 0; i < pmp->iroot->cluster.nchains; ++i) {
 		for (j = 0; j < hammer2_xop_nthreads; ++j) {
 			if (pmp->xop_groups[j].thrs[i].td)
@@ -453,6 +491,8 @@
 	int i;
 	int j;
 
+	kprintf("DF2621: helper_cleanup enter pmp=%p groups=%p nmasters=%d\n",
+		pmp, pmp->xop_groups, pmp->pfs_nmasters);
 	if (pmp->xop_groups == NULL) {
 		KKASSERT(pmp->has_xop_threads == 0);
 		return;
@@ -463,8 +503,11 @@
 			if (pmp->xop_groups[j].thrs[i].td)
 				hammer2_thr_delete(&pmp->xop_groups[j].thrs[i]);
 		}
+		kprintf("DF2621: helper_cleanup col %d deleted\n", i);
 	}
 	pmp->has_xop_threads = 0;
+	kprintf("DF2621: helper_cleanup freeing groups=%p\n",
+		pmp->xop_groups);
 	kfree(pmp->xop_groups, M_HAMMER2);
 	pmp->xop_groups = NULL;
 }
@@ -1076,6 +1119,7 @@
 	uint32_t hash[XOP_HASH_SIZE] = { 0 };
 	hammer2_xop_head_t *xop;
 
+	df2621_check_freed(thr, pmp);
 	hammer2_spin_ex(&pmp->xop_spin);
 	TAILQ_FOREACH(xop, &thr->xopq, collect[clindex].entry) {
 		/*
--- a/sys/vfs/hammer2/hammer2_vfsops.c	2026-08-28 15:24:47.454135445 +0000
+++ b/sys/vfs/hammer2/hammer2_vfsops.c	2026-08-28 15:25:09.545848774 +0000
@@ -718,7 +718,9 @@
 	if (chains_still_present) {
 		kprintf("hammer2: cannot free pmp %p, still in use\n", pmp);
 	} else {
+		extern void hammer2_df2621_mark_free(hammer2_pfs_t *);
 		kmalloc_destroy_obj(&pmp->minode);
+		hammer2_df2621_mark_free(pmp);
 		kfree(pmp, M_HAMMER2);
 	}
 }
@@ -743,6 +745,7 @@
 		wlist = &hammer2_pfslist;
 	else
 		wlist = &hammer2_spmplist;
+	kprintf("DF2621: pfsfree_scan hmp=%p which=%d enter\n", hmp, which);
 again:
 	TAILQ_FOREACH(pmp, wlist, mntentry) {
 		if ((iroot = pmp->iroot) == NULL)
@@ -769,6 +772,8 @@
 		 * Make sure all synchronization threads are locked
 		 * down.
 		 */
+		kprintf("DF2621: pfsfree_scan freeze begin pmp=%p groups=%p\n",
+			pmp, pmp->xop_groups);
 		for (i = 0; i < HAMMER2_MAXCLUSTER; ++i) {
 			if (pmp->pfs_hmps[i] == NULL)
 				continue;
@@ -807,6 +812,8 @@
 		/*
 		 * Remove the chain from matching elements of the PFS.
 		 */
+		kprintf("DF2621: pfsfree_scan delete cols begin pmp=%p hmp=%p\n",
+			pmp, hmp);
 		for (i = 0; i < HAMMER2_MAXCLUSTER; ++i) {
 			if (pmp->pfs_hmps[i] != hmp)
 				continue;
@@ -863,6 +870,7 @@
 			 */
 			KKASSERT(TAILQ_EMPTY(&pmp->syncq));
 			KKASSERT(TAILQ_EMPTY(&pmp->depq));
+			kprintf("DF2621: pfsfree_scan pmp empty -> pfsfree\n");
 			hammer2_pfsfree(pmp);
 			goto again;
 		}
@@ -871,6 +879,7 @@
 		 * If elements still remain we need to set the REMASTER
 		 * flag and unfreeze it.
 		 */
+		kprintf("DF2621: pfsfree_scan unfreeze+remaster pmp=%p\n", pmp);
 		for (i = 0; i < HAMMER2_MAXCLUSTER; ++i) {
 			if (pmp->pfs_hmps[i] == NULL)
 				continue;