Skip to content

Fix use-after-free in extract() EXTR_REFS collision modes#22696

Open
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:fix/extract-refs-uaf
Open

Fix use-after-free in extract() EXTR_REFS collision modes#22696
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:fix/extract-refs-uaf

Conversation

@iliaal

@iliaal iliaal commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

The GH-18209 fix guarded php_extract_ref_overwrite against a destructor freeing the extract target during the reference write, but the five sibling EXTR_REFS collision paths still drop the old value before writing the reference. The added test crashes on master through the EXTR_IF_EXISTS and EXTR_PREFIX_ALL paths; the fix copies the old value aside and drops it after the write, matching php_extract_ref_overwrite.

Fixes GH-18209

The phpGH-18209 fix guarded only php_extract_ref_overwrite. The other five
per-collision-mode helpers (if_exists, prefix_if_exists, prefix_same,
prefix_all, prefix_invalid), split out when extract() was refactored,
kept the pre-fix order: they dropped the old value of orig_var before
writing the new reference. A destructor run by that drop can unset the
symbol being written, so the following ZVAL_REF wrote into freed memory.
Apply the same swap-then-dtor already used by php_extract_ref_overwrite:
copy the old value aside, write the reference, then drop the copy.

Fixes phpGH-18209
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.

Use-after-free with extract() and EXTR_REFS

1 participant