Skip to content

Heap-use-after-free in gc_check_possible_root with lazy proxy #20877

@vi3tL0u1s

Description

@vi3tL0u1s

Description

This appears related to #20861 but demonstrates a confirmed UAF in gc_check_possible_root via a different execution path.

The following code:

<?php
class A {
    public $_;
    public function __get($n) {
        global $obj;
        $obj->f ??= $r =& $this->b;
        static $a = $a;
        $ $v = $z;
        $this->$ $v &= $z;
        $this->$ $v &= $obj->$n;
    }
}
$rc = new ReflectionClass(A::class);
$obj = $rc->newLazyProxy(fn() => new A);
$rc->initializeLazyObject($obj);
var_dump($obj->p);

Crash Output (with USE_ZEND_ALLOC=0)

==ERROR: AddressSanitizer: heap-use-after-free on address 0x503000023504 at pc 0x55663e854dee bp 0x7fffd3877e60 sp 0x7fffd3877e50
READ of size 4 at 0x503000023504 thread T0
    #0 in gc_check_possible_root /path/to/php-src/Zend/zend_gc.h:98
    #1 in i_zval_ptr_dtor /path/to/php-src/Zend/zend_variables.h:47
    #2 in i_free_compiled_variables /path/to/php-src/Zend/zend_execute.c:4276
    #3 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116383
    #4 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1010
    #5 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1104
    #6 in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860
    #7 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872
    #8 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:245
    #9 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:932
    #10 in zend_fetch_property_address /path/to/php-src/Zend/zend_execute.c:3616
    #11 in ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34789
    ...

0x503000023504 is located 4 bytes inside of 32-byte region [0x503000023500,0x503000023520)
freed by thread T0 here:
    #0 in __interceptor_free
    #1 in __zend_free /path/to/php-src/Zend/zend_alloc.c:3571
    #2 in _efree /path/to/php-src/Zend/zend_alloc.c:2790
    #3 in zend_reference_destroy /path/to/php-src/Zend/zend_variables.c:75
    #4 in rc_dtor_func /path/to/php-src/Zend/zend_variables.c:57
    #5 in i_zval_ptr_dtor /path/to/php-src/Zend/zend_variables.h:45
    #6 in i_free_compiled_variables /path/to/php-src/Zend/zend_execute.c:4276
    ...

previously allocated by thread T0 here:
    #0 in __interceptor_malloc
    #1 in __zend_malloc /path/to/php-src/Zend/zend_alloc.c:3543
    #2 in _emalloc /path/to/php-src/Zend/zend_alloc.c:2780
    #3 in zend_assign_to_variable_reference /path/to/php-src/Zend/zend_execute.c:570
    #4 in ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:50885
    ...

SUMMARY: AddressSanitizer: heap-use-after-free /path/to/php-src/Zend/zend_gc.h:98 in gc_check_possible_root

Commit

eea9a62b1bb3e429e58259408e1beb6ca3f22305

Configurations

./configure --enable-debug --enable-address-sanitizer --disable-shared --with-pic --enable-mbstring --with-zlib

PHP Version

PHP 8.6.0-dev (cli) (built: Jan  9 2026 14:43:36) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.6.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.6.0-dev, Copyright (c), by Zend Technologies

Operating System

Ubuntu 22.04

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions