Skip to content

Memory out of bounds using dl() loading extension #19771

@matyhtf

Description

@matyhtf

Description

The following code:

<?php
dl('swoole.so');

The actual script file is the temporary file run_test_info.php generated by run_tests. php. Using the dl() function to load the extension will cause memory out of bounds, but it is OK to modify the php.ini to load the extension.

$ cat run-test-info.php
    <?php
    echo str_replace("Zend OPcache", "opcache", implode(",", get_loaded_extensions()));
    $ext_dir = ini_get("extension_dir");
    foreach (scandir($ext_dir) as $file) {
        if (!preg_match('/^(?:php_)?([_a-zA-Z0-9]+)\.(?:so|dll)$/', $file, $matches)) {
            continue;
        }
        $ext = $matches[1];
        if (!extension_loaded($ext) && @dl($file)) {
            echo ",", $ext;
        }
    }
    ?>

Resulted in this output:

$ export USE_ZEND_ALLOC=0
$ cat dl.php 
<?php
dl('swoole.so');

$ php dl.php 
corrupted double-linked list
Aborted (core dumped)

But I expected this output instead:
No memory error

The swoole_client.cc:169 code is:

zend_declare_property_long(swoole_client_ce, ZEND_STRL("errCode"), 0, ZEND_ACC_PUBLIC);

Only class properties are declared here

Valgrind

$ valgrind --num-callers=64 php dl.php 
==4137170== Memcheck, a memory error detector
==4137170== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4137170== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==4137170== Command: php dl.php
==4137170== 
==4137170== Invalid read of size 8
==4137170==    at 0x941867: destroy_zend_class (zend_opcode.c:439)
==4137170==    by 0x971613: _zend_hash_del_el_ex (zend_hash.c:1425)
==4137170==    by 0x97170E: _zend_hash_del_el (zend_hash.c:1452)
==4137170==    by 0x973987: zend_hash_apply_with_argument (zend_hash.c:2065)
==4137170==    by 0x963DE0: clean_module_classes (zend_API.c:3021)
==4137170==    by 0x963EAF: module_destructor (zend_API.c:3058)
==4137170==    by 0x9644FC: zend_post_deactivate_modules (zend_API.c:3184)
==4137170==    by 0x8AC518: php_request_shutdown (main.c:1906)
==4137170==    by 0xAD9CD7: do_cli (php_cli.c:1136)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170==  Address 0x907f6d0 is 32 bytes inside a block of size 56 free'd
==4137170==    at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0x9418B4: destroy_zend_class (zend_opcode.c:442)
==4137170==    by 0x971613: _zend_hash_del_el_ex (zend_hash.c:1425)
==4137170==    by 0x97170E: _zend_hash_del_el (zend_hash.c:1452)
==4137170==    by 0x973987: zend_hash_apply_with_argument (zend_hash.c:2065)
==4137170==    by 0x963DE0: clean_module_classes (zend_API.c:3021)
==4137170==    by 0x963EAF: module_destructor (zend_API.c:3058)
==4137170==    by 0x9644FC: zend_post_deactivate_modules (zend_API.c:3184)
==4137170==    by 0x8AC518: php_request_shutdown (main.c:1906)
==4137170==    by 0xAD9CD7: do_cli (php_cli.c:1136)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170==  Block was alloc'd at
==4137170==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0x915E04: __zend_malloc (zend_alloc.c:3123)
==4137170==    by 0x968008: zend_declare_typed_property (zend_API.c:4219)
==4137170==    by 0x96903C: zend_declare_property_ex (zend_API.c:4463)
==4137170==    by 0x9690A6: zend_declare_property (zend_API.c:4470)
==4137170==    by 0x969200: zend_declare_property_long (zend_API.c:4498)
==4137170==    by 0x96A9680: php_swoole_client_minit (swoole_client.cc:169)
==4137170==    by 0x97743EF: zm_startup_swoole(int, int) (php_swoole.cc:871)
==4137170==    by 0x960E05: zend_startup_module_ex (zend_API.c:2236)
==4137170==    by 0x77669F: php_load_extension (dl.c:257)
==4137170==    by 0x776772: php_dl (dl.c:300)
==4137170==    by 0x775F69: zif_dl (dl.c:69)
==4137170==    by 0x99A241: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1250)
==4137170==    by 0xA13293: execute_ex (zend_vm_execute.h:56101)
==4137170==    by 0xA18AE5: zend_execute (zend_vm_execute.h:60469)
==4137170==    by 0x957399: zend_execute_scripts (zend.c:1844)
==4137170==    by 0x8AD935: php_execute_script (main.c:2579)
==4137170==    by 0xAD9472: do_cli (php_cli.c:964)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170== 
==4137170== Invalid read of size 4
==4137170==    at 0x93FD07: zend_string_release (zend_string.h:322)
==4137170==    by 0x941886: destroy_zend_class (zend_opcode.c:440)
==4137170==    by 0x971613: _zend_hash_del_el_ex (zend_hash.c:1425)
==4137170==    by 0x97170E: _zend_hash_del_el (zend_hash.c:1452)
==4137170==    by 0x9734F7: zend_hash_graceful_reverse_destroy (zend_hash.c:1977)
==4137170==    by 0x95525E: zend_shutdown (zend.c:1110)
==4137170==    by 0x8AD5BF: php_module_shutdown (main.c:2454)
==4137170==    by 0xADA1E2: main (php_cli.c:1347)
==4137170==  Address 0x906f3a4 is 4 bytes inside a block of size 40 free'd
==4137170==    at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0x91492D: _efree_custom (zend_alloc.c:2487)
==4137170==    by 0x914A84: _efree (zend_alloc.c:2607)
==4137170==    by 0xA37537: _str_dtor (zend_string.c:68)
==4137170==    by 0x97238F: zend_hash_destroy (zend_hash.c:1701)
==4137170==    by 0xA37F55: zend_interned_strings_deactivate (zend_string.c:348)
==4137170==    by 0x8AC5D0: php_request_shutdown (main.c:1926)
==4137170==    by 0xAD9CD7: do_cli (php_cli.c:1136)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170==  Block was alloc'd at
==4137170==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0x915E04: __zend_malloc (zend_alloc.c:3123)
==4137170==    by 0x9148BC: _malloc_custom (zend_alloc.c:2478)
==4137170==    by 0x914A06: _emalloc (zend_alloc.c:2597)
==4137170==    by 0xA36DC1: zend_string_alloc (zend_string.h:152)
==4137170==    by 0xA36E34: zend_string_init (zend_string.h:174)
==4137170==    by 0xA37BAE: zend_new_interned_string_request (zend_string.c:253)
==4137170==    by 0x968655: zend_declare_typed_property (zend_API.c:4291)
==4137170==    by 0x96903C: zend_declare_property_ex (zend_API.c:4463)
==4137170==    by 0x9690A6: zend_declare_property (zend_API.c:4470)
==4137170==    by 0x96917E: zend_declare_property_bool (zend_API.c:4489)
==4137170==    by 0x994EC1D: curl_multi_register_class (multi.cc:613)
==4137170==    by 0x9940068: swoole_native_curl_minit (interface.cc:240)
==4137170==    by 0x96D4F98: php_swoole_runtime_minit (swoole_runtime.cc:279)
==4137170==    by 0x97743D5: zm_startup_swoole(int, int) (php_swoole.cc:868)
==4137170==    by 0x960E05: zend_startup_module_ex (zend_API.c:2236)
==4137170==    by 0x77669F: php_load_extension (dl.c:257)
==4137170==    by 0x776772: php_dl (dl.c:300)
==4137170==    by 0x775F69: zif_dl (dl.c:69)
==4137170==    by 0x99A241: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1250)
==4137170==    by 0xA13293: execute_ex (zend_vm_execute.h:56101)
==4137170==    by 0xA18AE5: zend_execute (zend_vm_execute.h:60469)
==4137170==    by 0x957399: zend_execute_scripts (zend.c:1844)
==4137170==    by 0x8AD935: php_execute_script (main.c:2579)
==4137170==    by 0xAD9472: do_cli (php_cli.c:964)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170== 
==4137170== Invalid read of size 4
==4137170==    at 0xA19F8A: zend_string_release_ex (zend_string.h:331)
==4137170==    by 0xA1A4B8: free_ini_entry (zend_ini.c:85)
==4137170==    by 0x9723CD: zend_hash_destroy (zend_hash.c:1706)
==4137170==    by 0xA1A59C: zend_ini_dtor (zend_ini.c:118)
==4137170==    by 0xA1A57D: zend_ini_shutdown (zend_ini.c:112)
==4137170==    by 0x8AD5E7: php_module_shutdown (main.c:2471)
==4137170==    by 0xADA1E2: main (php_cli.c:1347)
==4137170==  Address 0x9020964 is 4 bytes inside a block of size 48 free'd
==4137170==    at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0xA37512: _str_dtor (zend_string.c:68)
==4137170==    by 0x97238F: zend_hash_destroy (zend_hash.c:1701)
==4137170==    by 0xA37F55: zend_interned_strings_deactivate (zend_string.c:348)
==4137170==    by 0x8AC5D0: php_request_shutdown (main.c:1926)
==4137170==    by 0xAD9CD7: do_cli (php_cli.c:1136)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170==  Block was alloc'd at
==4137170==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0x915E04: __zend_malloc (zend_alloc.c:3123)
==4137170==    by 0xA36D94: zend_string_alloc (zend_string.h:152)
==4137170==    by 0xA36E34: zend_string_init (zend_string.h:174)
==4137170==    by 0xA37E07: zend_string_init_interned_request (zend_string.c:315)
==4137170==    by 0xA1A845: zend_register_ini_entries_ex (zend_ini.c:228)
==4137170==    by 0x97714AC: zm_startup_swoole(int, int) (php_swoole.cc:490)
==4137170==    by 0x960E05: zend_startup_module_ex (zend_API.c:2236)
==4137170==    by 0x77669F: php_load_extension (dl.c:257)
==4137170==    by 0x776772: php_dl (dl.c:300)
==4137170==    by 0x775F69: zif_dl (dl.c:69)
==4137170==    by 0x99A241: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1250)
==4137170==    by 0xA13293: execute_ex (zend_vm_execute.h:56101)
==4137170==    by 0xA18AE5: zend_execute (zend_vm_execute.h:60469)
==4137170==    by 0x957399: zend_execute_scripts (zend.c:1844)
==4137170==    by 0x8AD935: php_execute_script (main.c:2579)
==4137170==    by 0xAD9472: do_cli (php_cli.c:964)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170== 
==4137170== Invalid read of size 4
==4137170==    at 0xA19F09: zend_string_release (zend_string.h:322)
==4137170==    by 0xA1A4D5: free_ini_entry (zend_ini.c:87)
==4137170==    by 0x9723CD: zend_hash_destroy (zend_hash.c:1706)
==4137170==    by 0xA1A59C: zend_ini_dtor (zend_ini.c:118)
==4137170==    by 0xA1A57D: zend_ini_shutdown (zend_ini.c:112)
==4137170==    by 0x8AD5E7: php_module_shutdown (main.c:2471)
==4137170==    by 0xADA1E2: main (php_cli.c:1347)
==4137170==  Address 0x90209d4 is 4 bytes inside a block of size 32 free'd
==4137170==    at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0xA37512: _str_dtor (zend_string.c:68)
==4137170==    by 0x97238F: zend_hash_destroy (zend_hash.c:1701)
==4137170==    by 0xA37F55: zend_interned_strings_deactivate (zend_string.c:348)
==4137170==    by 0x8AC5D0: php_request_shutdown (main.c:1926)
==4137170==    by 0xAD9CD7: do_cli (php_cli.c:1136)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170==  Block was alloc'd at
==4137170==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4137170==    by 0x915E04: __zend_malloc (zend_alloc.c:3123)
==4137170==    by 0xA36D94: zend_string_alloc (zend_string.h:152)
==4137170==    by 0xA36E34: zend_string_init (zend_string.h:174)
==4137170==    by 0xA37E07: zend_string_init_interned_request (zend_string.c:315)
==4137170==    by 0xA1A9FD: zend_register_ini_entries_ex (zend_ini.c:256)
==4137170==    by 0x97714AC: zm_startup_swoole(int, int) (php_swoole.cc:490)
==4137170==    by 0x960E05: zend_startup_module_ex (zend_API.c:2236)
==4137170==    by 0x77669F: php_load_extension (dl.c:257)
==4137170==    by 0x776772: php_dl (dl.c:300)
==4137170==    by 0x775F69: zif_dl (dl.c:69)
==4137170==    by 0x99A241: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1250)
==4137170==    by 0xA13293: execute_ex (zend_vm_execute.h:56101)
==4137170==    by 0xA18AE5: zend_execute (zend_vm_execute.h:60469)
==4137170==    by 0x957399: zend_execute_scripts (zend.c:1844)
==4137170==    by 0x8AD935: php_execute_script (main.c:2579)
==4137170==    by 0xAD9472: do_cli (php_cli.c:964)
==4137170==    by 0xADA179: main (php_cli.c:1334)
==4137170== 
==4137170== 
==4137170== HEAP SUMMARY:
==4137170==     in use at exit: 36,562 bytes in 31 blocks
==4137170==   total heap usage: 57,098 allocs, 57,067 frees, 12,624,109 bytes allocated
==4137170== 
==4137170== LEAK SUMMARY:
==4137170==    definitely lost: 0 bytes in 0 blocks
==4137170==    indirectly lost: 0 bytes in 0 blocks
==4137170==      possibly lost: 0 bytes in 0 blocks
==4137170==    still reachable: 36,562 bytes in 31 blocks
==4137170==         suppressed: 0 bytes in 0 blocks
==4137170== Rerun with --leak-check=full to see details of leaked memory
==4137170== 
==4137170== For lists of detected and suppressed errors, rerun with: -s
==4137170== ERROR SUMMARY: 112 errors from 4 contexts (suppressed: 0 from 0)

PHP Version

PHP 8.2.29 (cli) (built: Sep  2 2025 19:22:09) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.2.29, Copyright (c) Zend Technologies

Operating System

Ubuntu 22.04

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions