DragonFlyBSD Kernel Audit
DF-2621 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_admin.c
+++ b/sys/vfs/hammer2/hammer2_admin.c
@@ -431,9 +431,21 @@
 	lockmgr(&pmp->lock, LK_EXCLUSIVE);
 	pmp->has_xop_threads = 1;
 
-	pmp->xop_groups = kmalloc(hammer2_xop_nthreads *
-				  sizeof(hammer2_xop_group_t),
-				  M_HAMMER2, M_WAITOK | M_ZERO);
+	/*
+	 * DF-2621: only allocate the group array once.  This function can
+	 * be called multiple times on the same pmp (hammer2_pfsalloc()
+	 * merging another same-clid device into a mounted pmp, the mount
+	 * helper, and xop_start's lazy setup).  Unconditionally assigning
+	 * a fresh kmalloc() here loses the old array pointer, leaking it
+	 * and orphaning its kernel threads (they are only ever signalled
+	 * through the array stored in pmp->xop_groups).  Keep the existing
+	 * array and just create any missing threads below.
+	 */
+	if (pmp->xop_groups == NULL) {
+		pmp->xop_groups = kmalloc(hammer2_xop_nthreads *
+					  sizeof(hammer2_xop_group_t),
+					  M_HAMMER2, M_WAITOK | M_ZERO);
+	}
 	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)