Skip to content

Heap buffer overflow in property hooks (zho_build_properties_ex) via re-entrant getter during var_export() #20479

@vi3tL0u1s

Description

@vi3tL0u1s

Description

The following code:

<?php
#[AllowDynamicProperties]
class ByRef {
    private $_virtualByRef = 'virtualByRef';
    public $virtualByRef {
        &get {
          return $this->_virtualByRef;
        }
        set {
          $this->_virtualByRef = $value;
        }
    }
    public $virtualSetOnly {
        set {
        }
    }
    public function __construct() {
        $this->undef = 'dynamic';
        $this->dynamic = 'dynamic';
    }
}
#[AllowDynamicProperties]
class ByVal extends ByRef {
    private $_virtualByVal = 'virtualByVal';
    public $virtualByVal {
        get {
          return $this->_virtualByVal;
        }
        set {
          $this->_virtualByVal = $value;
        }
    }
    public $backed = 'backed' {
        get {
          return $this->backed;
        }
        set {
          $this->backed = $value;
        }
    }
    public string $backedUninixialized {
        get {
            $this->_this = $this->_thisx= $this;
            $a[0] =//////
            var_export($this);
            return $this->backedUninitialized;
        }
        set {
            $this->backedUninitialized = $value;
        }
    }
}
function testByVal($object) {
    foreach ($object as $prop => $value) {
        $object->{$prop}!= strtoupper($value);
    }
    var_dump($object);
}

testByVal(new ByVal);
testByVal(new ByRef);

Resulted in this output:

=================================================================
==2914108==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61200002f580 at pc 0x558dee39b4fe bp 0x7ffd74ab0f50 sp 0x7ffd74ab0f48
WRITE of size 8 at 0x61200002f580 thread T0
    #0 0x558dee39b4fd in _zend_hash_append_ex /path/to/php-src/Zend/zend_hash.h:1641:2
    #1 0x558dee39afa6 in _zend_hash_append /path/to/php-src/Zend/zend_hash.h:1659:9
    #2 0x558dee39a060 in zho_build_properties_ex /path/to/php-src/Zend/zend_property_hooks.c:124:16
    #3 0x558dee39921c in zend_hooked_object_build_properties /path/to/php-src/Zend/zend_property_hooks.c:141:9
    #4 0x558dee3539e6 in zend_std_get_properties_for /path/to/php-src/Zend/zend_object_handlers.c:2508:12
    #5 0x558dee353e67 in zend_get_properties_for /path/to/php-src/Zend/zend_object_handlers.c:2546:9
    #6 0x558dedad55ce in php_var_export_ex /path/to/php-src/ext/standard/var.c:603:11
    #7 0x558dedad7b58 in zif_var_export /path/to/php-src/ext/standard/var.c:707:23
    #8 0x558dee140bd1 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:1421:2
    #9 0x558dedfabf42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #10 0x558dedf86571 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #11 0x558dedf88782 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #12 0x558dee3546ea in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:862:2
    #13 0x558dee33a7fb in zend_call_known_instance_method_with_0_params /path/to/php-src/Zend/zend_API.h:868:2
    #14 0x558dee340bfe in zend_call_get_hook /path/to/php-src/Zend/zend_object_handlers.c:733:2
    #15 0x558dee33e731 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:847:8
    #16 0x558dede7242b in zend_read_property_ex /path/to/php-src/Zend/zend_API.c:5122:10
    #17 0x558dee39cd5e in zho_declared_it_fetch_current /path/to/php-src/Zend/zend_property_hooks.c:179:17
    #18 0x558dee39c7b8 in zho_it_fetch_current /path/to/php-src/Zend/zend_property_hooks.c:262:4
    #19 0x558dee39bc4c in zho_it_valid /path/to/php-src/Zend/zend_property_hooks.c:288:2
    #20 0x558dee1f80d4 in zend_fe_fetch_object_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:3102:8
    #21 0x558dee0c44e9 in ZEND_FE_FETCH_R_SPEC_VAR_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:23604:3
    #22 0x558dedfabf42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #23 0x558dedfac847 in zend_execute /path/to/php-src/Zend/zend_vm_execute.h:121924:2
    #24 0x558dee3dffd0 in zend_execute_script /path/to/php-src/Zend/zend.c:1975:3
    #25 0x558dedbe07ab in php_execute_script_ex /path/to/php-src/main/main.c:2640:13
    #26 0x558dedbe0ca8 in php_execute_script /path/to/php-src/main/main.c:2680:9
    #27 0x558dee3e7ed2 in do_cli /path/to/php-src/sapi/cli/php_cli.c:951:5
    #28 0x558dee3e4e2c in main /path/to/php-src/sapi/cli/php_cli.c:1362:18
    #29 0x7fdf152f7d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 4f7b0c955c3d81d7cac1501a2498b69d1d82bfe7)
    #30 0x7fdf152f7e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 4f7b0c955c3d81d7cac1501a2498b69d1d82bfe7)
    #31 0x558dec803374 in _start (/path/to/php-src/sapi/cli/php+0x603374) (BuildId: 7e30eed09f929fbd58cc0b481c8117cf438919d5)

0x61200002f580 is located 0 bytes to the right of 320-byte region [0x61200002f440,0x61200002f580)
allocated by thread T0 here:
    #0 0x558dec8861be in malloc (/path/to/php-src/sapi/cli/php+0x6861be) (BuildId: 7e30eed09f929fbd58cc0b481c8117cf438919d5)
    #1 0x558dede2f143 in __zend_malloc /path/to/php-src/Zend/zend_alloc.c:3543:14
    #2 0x558dede2ead0 in _emalloc /path/to/php-src/Zend/zend_alloc.c:2780:10
    #3 0x558dee23a1ff in zend_hash_real_init_mixed_ex /path/to/php-src/Zend/zend_hash.c:176:10
    #4 0x558dee23a037 in zend_hash_real_init_mixed /path/to/php-src/Zend/zend_hash.c:342:2
    #5 0x558dee3993b4 in zho_build_properties_ex /path/to/php-src/Zend/zend_property_hooks.c:61:2
    #6 0x558dee39921c in zend_hooked_object_build_properties /path/to/php-src/Zend/zend_property_hooks.c:141:9
    #7 0x558dee3539e6 in zend_std_get_properties_for /path/to/php-src/Zend/zend_object_handlers.c:2508:12
    #8 0x558dee353e67 in zend_get_properties_for /path/to/php-src/Zend/zend_object_handlers.c:2546:9
    #9 0x558dedad55ce in php_var_export_ex /path/to/php-src/ext/standard/var.c:603:11
    #10 0x558dedad7b58 in zif_var_export /path/to/php-src/ext/standard/var.c:707:23
    #11 0x558dee140bd1 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:1421:2
    #12 0x558dedfabf42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #13 0x558dedf86571 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #14 0x558dedf88782 in zend_call_known_function /path/to/php-src/Zend/zend_execute_API.c:1108:23
    #15 0x558dee3546ea in zend_call_known_instance_method /path/to/php-src/Zend/zend_API.h:862:2
    #16 0x558dee33a7fb in zend_call_known_instance_method_with_0_params /path/to/php-src/Zend/zend_API.h:868:2
    #17 0x558dee340bfe in zend_call_get_hook /path/to/php-src/Zend/zend_object_handlers.c:733:2
    #18 0x558dee33e731 in zend_std_read_property /path/to/php-src/Zend/zend_object_handlers.c:847:8
    #19 0x558dede7242b in zend_read_property_ex /path/to/php-src/Zend/zend_API.c:5122:10
    #20 0x558dee39cd5e in zho_declared_it_fetch_current /path/to/php-src/Zend/zend_property_hooks.c:179:17
    #21 0x558dee39c7b8 in zho_it_fetch_current /path/to/php-src/Zend/zend_property_hooks.c:262:4
    #22 0x558dee39bc4c in zho_it_valid /path/to/php-src/Zend/zend_property_hooks.c:288:2
    #23 0x558dee1f80d4 in zend_fe_fetch_object_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:3102:8
    #24 0x558dee0c44e9 in ZEND_FE_FETCH_R_SPEC_VAR_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:23604:3
    #25 0x558dedfabf42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116212:12
    #26 0x558dedfac847 in zend_execute /path/to/php-src/Zend/zend_vm_execute.h:121924:2
    #27 0x558dee3dffd0 in zend_execute_script /path/to/php-src/Zend/zend.c:1975:3
    #28 0x558dedbe07ab in php_execute_script_ex /path/to/php-src/main/main.c:2640:13
    #29 0x558dedbe0ca8 in php_execute_script /path/to/php-src/main/main.c:2680:9

SUMMARY: AddressSanitizer: heap-buffer-overflow /path/to/php-src/Zend/zend_hash.h:1641:2 in _zend_hash_append_ex
Shadow bytes around the buggy address:
  0x0c247fffde60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c247fffde70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c247fffde80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c247fffde90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c247fffdea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c247fffdeb0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fffdec0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fffded0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fffdee0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fffdef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fffdf00: 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
==2914108==ABORTING

Commit:

9cd367362da5442861f30d3b41e967d641b90cbd

Build configuration:

CC="clang" CXX="clang++" CFLAGS="-fsanitize=address -g -O0" CXXFLAGS="-fsanitize=address -g -O0" ./configure --enable-debug --enable-address-sanitizer --disable-shared --with-pic

PHP Version

PHP 8.6.0-dev (cli) (built: Nov 14 2025 16:07:53) (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