Skip to content

Fix GH-23725: use-after-free when __toString() frees a frameless argument - #309

Closed
iliaal wants to merge 1 commit into
masterfrom
fix/gh-23725-frameless-arg-uaf
Closed

iliaal wants to merge 1 commit into
masterfrom
fix/gh-23725-frameless-arg-uaf

Conversation

@iliaal

@iliaal iliaal commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Frameless calls hand the handler the caller's operand zvals without taking a reference, so an argument freed by a __toString() the handler triggers leaves it reading freed memory. Taking the reference in the Z_FLF_PARAM_ARRAY macros generalizes the per-function guards from 8ce7f7f, as suggested on php#23221, which this supersedes. Z_FLF_PARAM_STR still reads its string directly on the fast path, so phpGH-21639 stays open.

Fixes php#23725

…rgument

Frameless calls pass the caller's operand zvals straight to the handler
without taking a reference, so an argument freed by a __toString() that the
handler itself triggers leaves it reading freed memory. Take a reference on
array and array-or-string arguments in the Z_FLF_PARAM_ARRAY* macros and
release it at flf_clean, so a destructive write from userland separates the
array instead. The handle is kept in a local because the operand may be a
reference slot that userland overwrites. This covers in_array(),
preg_replace(), str_replace(), strtr() and implode(); the per-function guards
from 8ce7f7f stay, since implode/1 parses its argument without the macros
and php_implode() is public API. Z_FLF_PARAM_STR still reads its string
directly on the fast path, so phpGH-21639 stays open.

Fixes phpGH-23725
@iliaal

iliaal commented Sep 17, 2026

Copy link
Copy Markdown
Owner Author

Submitted upstream as php#23731.

@iliaal iliaal closed this Sep 17, 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.

heap uaf in php_pcre

1 participant