Skip to content

implode() / join(): Use-After-Free via Stringable::__toString() Array Mutation #23204

Description

@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
class Crash implements Stringable {
    public function __toString(): string {
        global $a;
        $a = null;
        return "X";
    }
}

$a = [new Crash, 2, 3, 4];
implode(",", $a);
==641665==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ab10ede4640 at pc 0x55fdef4aa314 bp 0x7ffc139481d0 sp 0x7ffc139481c8
READ of size 1 at 0x7ab10ede4640 thread T0
    #0 0x55fdef4aa313 in zval_get_type /home/ilutov/Developer/php-src/Zend/zend_types.h:685
    #1 0x55fdef4bfd8b in php_implode /home/ilutov/Developer/php-src/ext/standard/string.c:946
    #2 0x55fdef4c20db in zflf_implode_2 /home/ilutov/Developer/php-src/ext/standard/string.c:1088
    #3 0x55fdefc87f4c in ZEND_FRAMELESS_ICALL_2_SPEC_HANDLER /home/ilutov/Developer/php-src/Zend/zend_vm_execute.h:3899
    #4 0x55fdeff006fa in execute_ex /home/ilutov/Developer/php-src/Zend/zend_vm_execute.h:110924

PHP Version

PHP 8.4+

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions