Skip to content

Fix GH-23204: use-after-free when __toString() destroys an array argument - #23207

Closed
lazerg wants to merge 4 commits into
php:PHP-8.4from
lazerg:fix/gh-23204-implode-uaf
Closed

Fix GH-23204: use-after-free when __toString() destroys an array argument#23207
lazerg wants to merge 4 commits into
php:PHP-8.4from
lazerg:fix/gh-23204-implode-uaf

Conversation

@lazerg

@lazerg lazerg commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

implode() walks the array with ZEND_HASH_FOREACH_VAL while holding no reference on it. Converting a Stringable element runs user code, and if that code drops the last remaining reference to the array ($a = null; from __toString()), arData is freed and the next iteration reads freed memory. strtr() and str_replace() read their array arguments the same way and crash the same way, so they are fixed here too.

Taking a reference on the table for the duration of the read keeps it alive and turns an in-place mutation into a separation instead, same as zend_compare_symbol_tables() does around zend_hash_compare(). In implode() the reference is released after the pieces have been concatenated, since the collected zend_strings are still owned by the array until then.

Fixes #23204.

Comment thread ext/standard/string.c
@lazerg lazerg changed the title Fix GH-23204: use-after-free in implode() when __toString() destroys the array Fix GH-23204: use-after-free when __toString() destroys an array argument Aug 10, 2026
@lazerg

lazerg commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

The Windows job failed on ext/pdo_odbc/tests/long_columns.phpt, which could not connect to its SQL Server instance. That is unrelated to this change.

@@ -0,0 +1,107 @@
--TEST--
GH-23204 (Use-after-free when __toString() destroys the array being read)
--FILE--

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please credit the reporter within --CREDITS--.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added, credited as iluuu1994.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not me, @e1abrador.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs say the CREDITS section should no longer be used. Should the wording be extended with a "unless reporters have to be credited"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, sorry. Changed to e1abrador.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs say the CREDITS section should no longer be used. Should the wording be extended with a "unless reporters have to be credited"?

The reasoning behind this is that git commits can track authors via Co-authored-by, which is complete bs. CREDITS section is a much more precise indication of authorship than a commit-wide author tag. So I purposefully ignore that docs and I believe that line should be removed.

@arnaud-lb arnaud-lb Aug 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like that this paragraph of the docs is only considering the case of the commit authors crediting themselves. It makes sense to me that no CREDITS section should be used in this case.

We could expand this paragraph with the case of committing a reproducer that was contributed by someone else.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I proposed a change in #23215

@devnexen devnexen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm once remark is addressed

Comment thread ext/standard/tests/strings/gh23204.phpt Outdated
Comment thread ext/standard/tests/strings/gh23204.phpt Outdated
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.

6 participants