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);