Skip to content

Heap-use-after-free in __zval_get_string_func during destructor handling with lazy proxy #20872

@vi3tL0u1s

Description

@vi3tL0u1s

Description

The following code:

<?php
class A {
    public $_;
    public function __get($n) {
        global $obj;
        unserialize(serialize($GLOBALS))[$k] = $obj->f ??= $r =& $this->b - $$c = new SplFixedArray(0);
    }
    function __destruct() {
        var_dump($obj->$name);
        return $this->x;
    }
}
class B extends A {}
$rc = new ReflectionClass(B::class);
$obj = $rc->newLazyProxy(function () { echo "i"; return new A; });
$r = $rc->initializeLazyObject($obj);
var_dump($r->p);

Resulted in this output: (without USE_ZEND_ALLOC=0)

AddressSanitizer:DEADLYSIGNAL
=================================================================
==3653114==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x561a3d92492d bp 0x7ffcf7f90d00 sp 0x7ffcf7f90c70 T0)
==3653114==The signal is caused by a READ memory access.
==3653114==Hint: this fault was caused by a dereference of a high value address (see register values below).  Dissassemble the provided pc to learn which register was used.
    #0 0x561a3d92492d in __zval_get_string_func /path/to/php-src/Zend/zend_operators.c:1088
    #1 0x561a3d924bca in zval_get_string_func /path/to/php-src/Zend/zend_operators.c:1109
    #2 0x561a3d54b4a7 in zval_get_tmp_string /path/to/php-src/Zend/zend_operators.h:349
    #3 0x561a3d54e327 in zend_wrong_property_read /path/to/php-src/Zend/zend_API.c:92
    #4 0x561a3d7e45f9 in ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:53823
    #5 0x561a3d808482 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:121702
    #6 0x561a3d64e9d8 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1010
    #7 0x561a3d64faff in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1104
    #8 0x561a3d90b991 in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860
    #9 0x561a3d90b9cb in zend_call_known_instance_method_with_0_params /path/to/php-src/Zend/zend_API.h:866
    #10 0x561a3d90c97a in zend_objects_destroy_object /path/to/php-src/Zend/zend_objects.c:172
    #11 0x561a3d909e0a in zend_objects_store_del /path/to/php-src/Zend/zend_objects_API.c:181
    #12 0x561a3d95bb31 in rc_dtor_func /path/to/php-src/Zend/zend_variables.c:57
    #13 0x561a3d830d2e in i_zval_ptr_dtor /path/to/php-src/Zend/zend_variables.h:45
    #14 0x561a3d83f77e in zend_array_destroy /path/to/php-src/Zend/zend_hash.c:1852
    #15 0x561a3d95bb31 in rc_dtor_func /path/to/php-src/Zend/zend_variables.c:57
    #16 0x561a3d655e78 in zval_ptr_dtor_nogc /path/to/php-src/Zend/zend_variables.h:36
    #17 0x561a3d67aa86 in cleanup_live_vars /path/to/php-src/Zend/zend_execute.c:4914
    #18 0x561a3d69ce6e in zend_dispatch_try_catch_finally_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:3370
    #19 0x561a3d69d877 in ZEND_HANDLE_EXCEPTION_SPEC_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:3455
    #20 0x561a3d7f4860 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116576
    #21 0x561a3d64e9d8 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1010
    #22 0x561a3d64faff in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1104
    #23 0x561a3d8f5236 in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860
    #24 0x561a3d8f52ab in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872
    #25 0x561a3d8f674a in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:245
    #26 0x561a3d8fb34c in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:932
    #27 0x561a3d7a830c in ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:44369
    #28 0x561a3d805632 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:120942
    #29 0x561a3d64e9d8 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1010
    #30 0x561a3d64faff in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1104
    #31 0x561a3d8f5236 in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860
    #32 0x561a3d8f52ab in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872
    #33 0x561a3d8f674a in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:245
    #34 0x561a3d8fb34c in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:932
    #35 0x561a3d771d4c in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34745
    #36 0x561a3d801ecb in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:120048
    #37 0x561a3d64e9d8 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1010
    #38 0x561a3d64faff in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1104
    #39 0x561a3d90b991 in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860
    #40 0x561a3d90b9cb in zend_call_known_instance_method_with_0_params /path/to/php-src/Zend/zend_API.h:866
    #41 0x561a3d90c97a in zend_objects_destroy_object /path/to/php-src/Zend/zend_objects.c:172
    #42 0x561a3d9090af in zend_objects_store_call_destructors /path/to/php-src/Zend/zend_objects_API.c:57
    #43 0x561a3d646e57 in shutdown_destructors /path/to/php-src/Zend/zend_execute_API.c:264
    #44 0x561a3d97242e in zend_call_destructors /path/to/php-src/Zend/zend.c:1342
    #45 0x561a3d39023e in php_request_shutdown /path/to/php-src/main/main.c:1985
    #46 0x561a3d97f87d in do_cli /path/to/php-src/sapi/cli/php_cli.c:1158
    #47 0x561a3d980489 in main /path/to/php-src/sapi/cli/php_cli.c:1362
    #48 0x7f15d2808d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #49 0x7f15d2808e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #50 0x561a3c406eb4 in _start (/path/to/php-src/sapi/cli/php+0x606eb4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /path/to/php-src/Zend/zend_operators.c:1088 in __zval_get_string_func
==3653114==ABORTING

Resulted in this output: (with USE_ZEND_ALLOC=0)

==3654094==ERROR: AddressSanitizer: heap-use-after-free on address 0x503000023d80 at pc 0x55e93db1bde8 bp 0x7fff6a4eb520 sp 0x7fff6a4eb510
READ of size 1 at 0x503000023d80 thread T0
    #0 0x55e93db1bde7 in zval_get_type /path/to/php-src/Zend/zend_types.h:662
    #1 0x55e93db24667 in __zval_get_string_func /path/to/php-src/Zend/zend_operators.c:1069
    #2 0x55e93db24bca in zval_get_string_func /path/to/php-src/Zend/zend_operators.c:1109
    #3 0x55e93d74b4a7 in zval_get_tmp_string /path/to/php-src/Zend/zend_operators.h:349
    #4 0x55e93d74e327 in zend_wrong_property_read /path/to/php-src/Zend/zend_API.c:92
    #5 0x55e93d9e45f9 in ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:53823
    #6 0x55e93da08482 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:121702
    ...
    #42 0x55e93db090af in zend_objects_store_call_destructors /path/to/php-src/Zend/zend_objects_API.c:57
    #43 0x55e93d846e57 in shutdown_destructors /path/to/php-src/Zend/zend_execute_API.c:264
    #44 0x55e93db7242e in zend_call_destructors /path/to/php-src/Zend/zend.c:1342
    #45 0x55e93d59023e in php_request_shutdown /path/to/php-src/main/main.c:1985

0x503000023d80 is located 16 bytes inside of 32-byte region [0x503000023d70,0x503000023d90)
freed by thread T0 here:
    #0 0x7f8ed65ee537 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x55e93d748fa5 in __zend_free /path/to/php-src/Zend/zend_alloc.c:3571
    #2 0x55e93d744d84 in _efree /path/to/php-src/Zend/zend_alloc.c:2790
    #3 0x55e93db5bdec in zend_reference_destroy /path/to/php-src/Zend/zend_variables.c:75
    #4 0x55e93db5bb31 in rc_dtor_func /path/to/php-src/Zend/zend_variables.c:57
    #5 0x55e93da30d2e in i_zval_ptr_dtor /path/to/php-src/Zend/zend_variables.h:45
    #6 0x55e93da409b2 in zend_symtable_clean /path/to/php-src/Zend/zend_hash.c:1972
    #7 0x55e93d8772e1 in zend_clean_and_cache_symbol_table /path/to/php-src/Zend/zend_execute.c:4262
    #8 0x55e93d8890f2 in zend_leave_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:1286
    #9 0x55e93d89cfd4 in zend_dispatch_try_catch_finally_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:3381

previously allocated by thread T0 here:
    #0 0x7f8ed65ee887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55e93d748e5d in __zend_malloc /path/to/php-src/Zend/zend_alloc.c:3543
    #2 0x55e93d744ca5 in _emalloc /path/to/php-src/Zend/zend_alloc.c:2780
    #3 0x55e93d85cb6a in zend_assign_to_variable_reference /path/to/php-src/Zend/zend_execute.c:570
    #4 0x55e93d9d264b 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_types.h:662 in zval_get_type

Commit

eea9a62b1bb

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions