[php-src] master: Detect immediate double-frees of zend_mm small slots

jvoisin via Arnaud Le Blanc <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: jvoisin (jvoisin)
Committer: Arnaud Le Blanc (arnaud-lb)
Date: 2026-08-27T13:25:07+02:00

Commit: https://github.com/php/php-src/commit/383b5bb7c579709fbb635fbea992b89307ec47cf
Raw diff: https://github.com/php/php-src/commit/383b5bb7c579709fbb635fbea992b89307ec47cf.diff

Detect immediate double-frees of zend_mm small slots

Freeing the same small pointer twice in a row pushed it onto the freelist
twice, so the next two allocations of that bin returned the same address.
That's a nifty primitive to obtain two live pointers of different
types to the same object. The shadow-pointer check does not catch it,
as both links are consistent.

This commit adds a simple check for when the freed pointer already is the head
of the freelist. heap->free_slot[bin_num] is loaded by the very next line, so
the check costs a single comparison on an already-hot value.

This only catches consecutive double-frees, not a free after other activity on
the same bin, but it doesn't cost ~anything performance wise, and catches real
bugs like error/cleanup paths freeing the same value twice. A quick look at `git log
--grep='double.free'` shows that this is a popular bug pattern.

Changed paths:
  M  Zend/zend_alloc.c


Diff:

diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 575b54b11a24..02de1a543da9 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -1430,6 +1430,12 @@ static zend_always_inline void zend_mm_free_small(zend_mm_heap *heap, void *ptr,
 #endif
 
 	p = (zend_mm_free_slot*)ptr;
+#if ZEND_MM_HEAP_PROTECTION
+	/* Catch the most common double-free pattern for free. */
+	if (UNEXPECTED(p == heap->free_slot[bin_num])) {
+		zend_mm_panic("zend_mm_heap corrupted (double free)");
+	}
+#endif
 	zend_mm_set_next_free_slot(heap, bin_num, p, heap->free_slot[bin_num]);
 	heap->free_slot[bin_num] = p;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.