[php-src] Issue #20613: Heap-Use-After-Free in zend_hash_num_elements() Triggered by Re-entrant Lazy Proxy __get() Access

[email protected] (vi3tL0u1s)
Newsgroups php.bugs
Message-ID <[email protected]>
Issue: https://github.com/php/php-src/issues/20613
Author: vi3tL0u1s

### Description

The following code:

```php
<?php
#[AllowDynamicProperties]
class RealInstance {
    public $_;
    public function __get($name) {
        global $obj;
        $a[@ $refleWto4]==$a[] =&$$a;
        $obj->foo ??=var_dump($arsay);
        unset($a[0][0]);
        $this->iterator[-! 0] = $this->_thisx= $this; 
        return $this->name;
    }
}
class Proxy extends RealInstance {}
$rc = new ReflectionClass(Proxy::class);
$obj = $rc->newLazyProxy(function () {
    return new Proxy;
});
$real = $rc->initializeLazyObject($obj);
var_dump($real->prop);
```

Resulted in this output:
```
=================================================================
==2670787==ERROR: AddressSanitizer: heap-use-after-free on address 0x60600001d67c at pc 0x559f9ad9c5dd bp 0x7ffc0f5aef30 sp 0x7ffc0f5aef28
READ of size 4 at 0x60600001d67c thread T0
    #0 0x559f9ad9c5dc in zend_hash_num_elements /path/to/php-src/Zend/zend_hash.h:321:13
    #1 0x559f9adba67c in i_zend_is_true /path/to/php-src/Zend/zend_operators.h:427:8
    #2 0x559f9ada8484 in zend_is_true /path/to/php-src/Zend/zend_operators.c:2907:9
    #3 0x559f9adb382c in zend_compare /path/to/php-src/Zend/zend_operators.c:2440:14
    #4 0x559f9ac11a36 in zend_is_equal_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:602:8
    #5 0x559f9a9fad1d in ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:17852:2
    #6 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #7 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #8 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #9 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #10 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #11 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #12 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #13 0x559f9ac2de33 in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34745:12
    #14 0x559f9ab0038c in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34776:2
    #15 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #16 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #17 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #18 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #19 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #20 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #21 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #22 0x559f9ac1bb9b in zend_fetch_property_address /path/to/php-src/Zend/zend_execute.c:3617:9
    #23 0x559f9ab0c474 in ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34789:2
    #24 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #25 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #26 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #27 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #28 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #29 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #30 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #31 0x559f9ab1c587 in ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:44369:12
    #32 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #33 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #34 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #35 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #36 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #37 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #38 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #39 0x559f9ac2ff42 in ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:44194:12
    #40 0x559f9ab0493c in ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:44225:2
    #41 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #42 0x559f9a9dc447 in zend_execute /path/to/php-src/Zend/zend_vm_execute.h:121924:2
    #43 0x559f9ae0a840 in zend_execute_script /path/to/php-src/Zend/zend.c:1975:3
    #44 0x559f9a6116a6 in php_execute_script_ex /path/to/php-src/main/main.c:2645:13
    #45 0x559f9a611ba8 in php_execute_script /path/to/php-src/main/main.c:2685:9
    #46 0x559f9ae126f2 in do_cli /path/to/php-src/sapi/cli/php_cli.c:951:5
    #47 0x559f9ae0f64c in main /path/to/php-src/sapi/cli/php_cli.c:1362:18
    #48 0x7f61d1f6cd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 4f7b0c955c3d81d7cac1501a2498b69d1d82bfe7)
    #49 0x7f61d1f6ce3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 4f7b0c955c3d81d7cac1501a2498b69d1d82bfe7)
    #50 0x559f99601d64 in _start (/path/to/php-src/sapi/cli/php+0x601d64) (BuildId: c796c67d00a301c05dcdb6ffc0fc26fabdb72f60)

0x60600001d67c is located 28 bytes inside of 56-byte region [0x60600001d660,0x60600001d698)
freed by thread T0 here:
    #0 0x559f99684902 in free (/path/to/php-src/sapi/cli/php+0x684902) (BuildId: c796c67d00a301c05dcdb6ffc0fc26fabdb72f60)
    #1 0x559f9a85bdb3 in __zend_free /path/to/php-src/Zend/zend_alloc.c:3571:2
    #2 0x559f9a85ff74 in _efree /path/to/php-src/Zend/zend_alloc.c:2790:3
    #3 0x559f9ac801ad in zend_array_destroy /path/to/php-src/Zend/zend_hash.c:1879:2
    #4 0x559f9adeaaa6 in rc_dtor_func /path/to/php-src/Zend/zend_variables.c:57:2
    #5 0x559f9aa97fc2 in ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:29787:3
    #6 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #7 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #8 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #9 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #10 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #11 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #12 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #13 0x559f9ac2de33 in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34745:12
    #14 0x559f9ab0038c in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34776:2
    #15 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #16 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #17 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #18 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #19 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #20 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #21 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #22 0x559f9ac1bb9b in zend_fetch_property_address /path/to/php-src/Zend/zend_execute.c:3617:9
    #23 0x559f9ab0c474 in ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34789:2
    #24 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #25 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #26 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #27 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #28 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #29 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2

previously allocated by thread T0 here:
    #0 0x559f99684bae in __interceptor_malloc (/path/to/php-src/sapi/cli/php+0x684bae) (BuildId: c796c67d00a301c05dcdb6ffc0fc26fabdb72f60)
    #1 0x559f9a8604e3 in __zend_malloc /path/to/php-src/Zend/zend_alloc.c:3543:14
    #2 0x559f9a85fe70 in _emalloc /path/to/php-src/Zend/zend_alloc.c:2780:10
    #3 0x559f9ac68a37 in _zend_new_array /path/to/php-src/Zend/zend_hash.c:290:18
    #4 0x559f9aa1673a in ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:25532:21
    #5 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #6 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #7 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #8 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #9 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #10 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #11 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #12 0x559f9ac1bb9b in zend_fetch_property_address /path/to/php-src/Zend/zend_execute.c:3617:9
    #13 0x559f9ab0c474 in ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:34789:2
    #14 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #15 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #16 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #17 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #18 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #19 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #20 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #21 0x559f9ab1c587 in ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:44369:12
    #22 0x559f9a9dbb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #23 0x559f9a9b617e in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #24 0x559f9a9b8382 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #25 0x559f9ad7f10a in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:860:2
    #26 0x559f9ad6f4f1 in zend_call_known_instance_method_with_1_params /path/to/php-src/Zend/zend_API.h:872:2
    #27 0x559f9ad6be45 in zend_std_call_getter /path/to/php-src/Zend/zend_object_handlers.c:242:2
    #28 0x559f9ad6a035 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:929:4
    #29 0x559f9ac2ff42 in ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:44194:12

SUMMARY: AddressSanitizer: heap-use-after-free /path/to/php-src/Zend/zend_hash.h:321:13 in zend_hash_num_elements
Shadow bytes around the buggy address:
  0x0c0c7fffba70: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x0c0c7fffba80: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa
  0x0c0c7fffba90: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fffbaa0: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 fa
  0x0c0c7fffbab0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
=>0x0c0c7fffbac0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd[fd]
  0x0c0c7fffbad0: fd fd fd fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x0c0c7fffbae0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fffbaf0: fd fd fd fd fd fd fd fd fa fa fa fa 00 00 00 00
  0x0c0c7fffbb00: 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fffbb10: 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
==2670787==ABORTING
```

Commit:
```
56795d2810e
```

Build configuration:
```
CC="clang" CXX="clang++" CFLAGS="-fsanitize=address -g -O0" CXXFLAGS="-fsanitize=address -g -O0" LDFLAGS="-fsanitize=address" ./buildconf --force && ./configure --enable-debug --enable-address-sanitizer --disable-shared --with-pic --enable-mbstring --with-zlib
```


### PHP Version

```plain
PHP 8.6.0-dev (cli) (built: Nov 29 2025 14:32:34) (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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.