[php-src] PR #23772: Bound the page count in the large-run free path (Zend/zend_alloc.c)
| From: | jvoisin | Date: | Sat, 19 Sep 2026 16:36:10 +0000 |
| Subject: | [php-src] PR #23772: Bound the page count in the large-run free path (Zend/zend_alloc.c) | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-38590@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/23772
Author: jvoisin
zend_mm_free_pages_ex() is the common sink for freeing large runs. It uses pages_count to reset bits
in chunk->free_map via zend_mm_bitset_reset_range() and to adjust chunk->free_pages, without
ever bounding page_num + pages_count to ZEND_MM_PAGES. That count is not trustworthy:
- In zend_mm_free_large(), it is decoded from the 10-bit ZEND_MM_LRUN_PAGES field of the page map
entry, so it can reach 1023 while a chunk only has 512 pages. The map lives in the chunk header,
right next to free_map, and is reachable by a heap overflow.
- In _efree_large(), it is computed straight from the caller-supplied size. The only cross-check
against the map is a pair of ZEND_ASSERT()s, which are compiled out under NDEBUG, so release builds
validate nothing beyond page alignment.
The realloc growth path already enforces this very invariant via page_num + new_pages_count <=
ZEND_MM_PAGES.