Skip to content

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

Closed
iliaal wants to merge 1 commit into
masterfrom
fix/extract-refs-uaf
Closed

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

Conversation

@iliaal

@iliaal iliaal commented Jul 11, 2026

Copy link
Copy Markdown
Owner

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, so a destructor run by that drop that frees the target symbol makes the following ZVAL_REF a use-after-free. This applies the same swap-then-dtor already used by php_extract_ref_overwrite (copy the old value aside, write the reference, then drop the copy). Reproduces with extract($a, EXTR_REFS | EXTR_IF_EXISTS) when the target variable holds an object whose destructor unsets it.

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
@iliaal iliaal force-pushed the fix/extract-refs-uaf branch from a9b7211 to 0247183 Compare July 11, 2026 12:10
@iliaal

iliaal commented Jul 11, 2026

Copy link
Copy Markdown
Owner Author

Submitted upstream as php#22696.

@iliaal iliaal closed this Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant