Skip to content

Detect immediate double-frees of zend_mm small slots - #23360

Open
jvoisin wants to merge 1 commit into
php:masterfrom
jvoisin:doublefree
Open

Detect immediate double-frees of zend_mm small slots#23360
jvoisin wants to merge 1 commit into
php:masterfrom
jvoisin:doublefree

Conversation

@jvoisin

@jvoisin jvoisin commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

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.

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.
@jvoisin

jvoisin commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Part of #14083

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant