From 669fafe30a03a0132e809341c0c1452af676c3a2 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 30 Jun 2026 15:56:37 -0400 Subject: [PATCH] Fix GH-22516: widen zend_mm srun free counter to cover bin 0 The per-page free-slot counter in zend_mm_gc() is stored in a 9-bit field (ZEND_MM_SRUN_FREE_COUNTER_MASK, max 511). Bin 0 holds 512 slots, so a fully-free bin-0 page drives the counter to 512, which overflows the field and reads back as 0; the counter == bin_elements checks then never fire and the page is never reclaimed. Widen the field to 10 bits (0x03ff0000); bit 25 was unused and the write side already stays below it for every other bin. Bin 0 is only reachable where ZEND_MM_MIN_USEABLE_BIN_SIZE == 8 (32-bit, or heap-protection-disabled builds). Fixes GH-22516 --- Zend/zend_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index d0f2b221b9a7..0b040743abf1 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -197,7 +197,7 @@ typedef zend_mm_bitset zend_mm_page_map[ZEND_MM_PAGE_MAP_LEN]; /* 64B */ #define ZEND_MM_SRUN_BIN_NUM_MASK 0x0000001f #define ZEND_MM_SRUN_BIN_NUM_OFFSET 0 -#define ZEND_MM_SRUN_FREE_COUNTER_MASK 0x01ff0000 +#define ZEND_MM_SRUN_FREE_COUNTER_MASK 0x03ff0000 #define ZEND_MM_SRUN_FREE_COUNTER_OFFSET 16 #define ZEND_MM_NRUN_OFFSET_MASK 0x01ff0000