Skip to content

Heap use-after-free in zval reference handling during function return (zend_gc_delref) #19945

@vi3tL0u1s

Description

@vi3tL0u1s

Description

The following code:

<?php

function &test(): int {
    $x = 0;
    try {
        return $x;
    } finally {
        $x = 
    $x = 0;
    try {
        return $x;
    } finally {
        $x = 'test';
    }
}

try {
    $x = &test();
    var_dump($x);
} catch (Error $e) {
    echo $e-'test';
    }
}

try {
    $x = &test();
    var_dump($x);
} catch (Error $e) {
    echo $e->getMessage(), "\n";
}

?>

Resulted in this output:

=================================================================
==1584160==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000020980 at pc 0x5619c3dad8d9 bp 0x7ffe9c708d10 sp 0x7ffe9c708d08
READ of size 4 at 0x603000020980 thread T0
    #0 0x5619c3dad8d8 in zend_gc_delref /path/to/php-src/Zend/zend_types.h:1383:2
    #1 0x5619c3fed0d2 in i_zval_ptr_dtor /path/to/php-src/Zend/zend_variables.h:44:8
    #2 0x5619c3db5d1f in i_free_compiled_variables /path/to/php-src/Zend/zend_execute.c:4276:3
    #3 0x5619c4002d95 in zend_leave_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:1195:3
    #4 0x5619c40185d7 in zend_dispatch_try_catch_finally_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:3381:3
    #5 0x5619c3f8a1c2 in ZEND_FAST_RET_SPEC_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:3554:2
    #6 0x5619c3dbeb42 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:115722:12
    #7 0x5619c3dbf447 in zend_execute /path/to/php-src/Zend/zend_vm_execute.h:121434:2
    #8 0x5619c41ee2f0 in zend_execute_script /path/to/php-src/Zend/zend.c:1977:3
    #9 0x5619c39f507b in php_execute_script_ex /path/to/php-src/main/main.c:2640:13
    #10 0x5619c39f5578 in php_execute_script /path/to/php-src/main/main.c:2680:9
    #11 0x5619c41f61f2 in do_cli /path/to/php-src/sapi/cli/php_cli.c:951:5
    #12 0x5619c41f314c in main /path/to/php-src/sapi/cli/php_cli.c:1362:18
    #13 0x7f9181b31d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #14 0x7f9181b31e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #15 0x5619c2603374 in _start (/path/to/php-src/sapi/cli/php+0x603374)

0x603000020980 is located 0 bytes inside of 32-byte region [0x603000020980,0x6030000209a0)
freed by thread T0 here:
    #0 0x5619c2685f12 in free (/path/to/php-src/sapi/cli/php+0x685f12)
    #1 0x5619c3c3dd63 in __zend_free /path/to/php-src/Zend/zend_alloc.c:3571:2
    #2 0x5619c3c41f24 in _efree /path/to/php-src/Zend/zend_alloc.c:2790:3
    #3 0x5619c41cfc71 in zend_reference_destroy /path/to/php-src/Zend/zend_variables.c:75:2
    #4 0x5619c41ce8f6 in rc_dtor_func /path/to/php-src/Zend/zend_variables.c:57:2
    #5 0x5619c41ce9e4 in i_zval_ptr_dtor /path/to/php-src/Zend/zend_variables.h:45:4
    #6 0x5619c41ce934 in zval_ptr_dtor /path/to/php-src/Zend/zend_variables.c:84:2
    #7 0x5619c4018181 in zend_dispatch_try_catch_finally_helper_SPEC /path/to/php-src/Zend/zend_vm_execute.h:3345:5

previously allocated by thread T0 here:
    #0 0x5619c26861be in malloc (/path/to/php-src/sapi/cli/php+0x6861be)
    #1 0x5619c3c42493 in __zend_malloc /path/to/php-src/Zend/zend_alloc.c:3543:14
    #2 0x5619c3c41e20 in _emalloc /path/to/php-src/Zend/zend_alloc.c:2780:10
    #3 0x5619c3f62dcf in ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER /path/to/php-src/Zend/zend_vm_execute.h:52394:5

SUMMARY: AddressSanitizer: heap-use-after-free /path/to/php-src/Zend/zend_types.h:1383:2 in zend_gc_delref

To reproduce:

USE_ZEND_ALLOC=0 ./php-src/sapi/cli/php poc.php

Commit:

0d4ff662e6d83fd3db0134fc826438307431335a

Configurations:

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.5.0-dev (cli)

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