DragonFlyBSD Kernel Audit
DF-1120 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/sym/sym_hipd.c b/sys/dev/disk/sym/sym_hipd.c
--- a/sys/dev/disk/sym/sym_hipd.c
+++ b/sys/dev/disk/sym/sym_hipd.c
@@ -474,6 +474,17 @@
 	a = (m_addr_t) ptr;
 
 	while (1) {
+		/*
+		 * Unconditional upper bound: h[] is sized
+		 * h[MEMO_CLUSTER_SHIFT - MEMO_SHIFT + 1], so index i must
+		 * never reach that size. s reaches MEMO_CLUSTER_SIZE exactly
+		 * when i is at the last valid index, so stop here regardless
+		 * of MEMO_FREE_UNUSED (which is normally compiled out).
+		 * Without this guard, two buddy-adjacent MEMO_CLUSTER_SIZE
+		 * frees push i past the array and corrupt the kernel heap.
+		 */
+		if (s >= MEMO_CLUSTER_SIZE)
+			break;
 #ifdef MEMO_FREE_UNUSED
 		if (s == MEMO_CLUSTER_SIZE) {
 			M_FREEP(a);