Skip to content

Use-after-free in GC when an exception is thrown #24989

Closed

Description

@vi3tL0u1s

Description

The following code:

<?php
class D { function __destruct() { gc_collect_cycles(); } }
foreach (range(1, 2) as $v) {
    $x = [new D, throw new Exception];
}

Resulted in this output:

=================================================================
==PID==ERROR: AddressSanitizer: heap-use-after-free on address 0x506000029124 at pc 0x5561c1f994c6 bp 0x7ffe55ec8c50 sp 0x7ffe55ec8c40
READ of size 4 at 0x506000029124 thread T0
    #0 0x5561c1f994c5 in zend_gc_remove_root_tmpvars php-src/Zend/zend_gc.c:2302
    #1 0x5561c1f97858 in zend_gc_collect_cycles php-src/Zend/zend_gc.c:2014
    #2 0x5561c1d0f4e4 in zif_gc_collect_cycles php-src/Zend/zend_builtin_functions.c:172
    #3 0x5561c1dfc48d in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER php-src/Zend/zend_vm_execute.h:1323
    #4 0x5561c1f6913a in execute_ex php-src/Zend/zend_vm_execute.h:110836
    #5 0x5561c1dc059b in zend_call_function php-src/Zend/zend_execute_API.c:1079
    #6 0x5561c1dc1a7c in zend_call_known_function_ex php-src/Zend/zend_execute_API.c:1185
    #7 0x5561c2081de9 in zend_call_known_function php-src/Zend/zend_API.h:895
    #8 0x5561c2081e5f in zend_call_known_instance_method php-src/Zend/zend_API.h:923
    #9 0x5561c2081e99 in zend_call_known_instance_method_with_0_params php-src/Zend/zend_API.h:929
    #10 0x5561c2082e9f in zend_objects_destroy_object php-src/Zend/zend_objects.c:171
    #11 0x5561c2080050 in zend_objects_store_del php-src/Zend/zend_objects_API.c:178
    #12 0x5561c20dac0d in rc_dtor_func php-src/Zend/zend_variables.c:56
    #13 0x5561c1fa6aa7 in i_zval_ptr_dtor php-src/Zend/zend_variables.h:44
    #14 0x5561c1fb58b3 in zend_array_destroy php-src/Zend/zend_hash.c:2071
    #15 0x5561c20dac0d in rc_dtor_func php-src/Zend/zend_variables.c:56
    #16 0x5561c1dc861f in zval_ptr_dtor_nogc php-src/Zend/zend_variables.h:35
    #17 0x5561c1ded873 in cleanup_live_vars php-src/Zend/zend_execute.c:4991
    #18 0x5561c1e120e0 in zend_dispatch_try_catch_finally_helper_SPEC php-src/Zend/zend_vm_execute.h:3384
    #19 0x5561c1e127a9 in ZEND_HANDLE_EXCEPTION_SPEC_HANDLER php-src/Zend/zend_vm_execute.h:3458
    #20 0x5561c1f699c2 in execute_ex php-src/Zend/zend_vm_execute.h:110976
    #21 0x5561c1f7d33d in zend_execute php-src/Zend/zend_vm_execute.h:116055
    #22 0x5561c20f6df4 in zend_execute_script php-src/Zend/zend.c:1986
    #23 0x5561c1ae4441 in php_execute_script_ex php-src/main/main.c:2636
    #24 0x5561c1ae499e in php_execute_script php-src/main/main.c:2676
    #25 0x5561c20fcb86 in do_cli php-src/sapi/cli/php_cli.c:941
    #26 0x5561c20ff363 in do_php_cli php-src/sapi/cli/php_cli.c:1354
    #27 0x5561c20f7c3e in main php-src/sapi/cli/php_cli_main.c:18
    #28 0x7f62c13b9d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    #29 0x7f62c13b9e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #30 0x5561c0a06ef4 in _start (php-src/sapi/cli/php+0x606ef4)

0x506000029124 is located 4 bytes inside of 56-byte region [0x506000029120,0x506000029158)
freed by thread T0 here:
    #0 0x7f62c1b54537 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x5561c1cb3c68 in __zend_free php-src/Zend/zend_alloc.c:4100
    #2 0x5561c1cad330 in _efree php-src/Zend/zend_alloc.c:3052
    #3 0x5561c1fb5c86 in zend_array_destroy php-src/Zend/zend_hash.c:2106
    #4 0x5561c20dac0d in rc_dtor_func php-src/Zend/zend_variables.c:56
    #5 0x5561c1dc861f in zval_ptr_dtor_nogc php-src/Zend/zend_variables.h:35
    #6 0x5561c1ded97f in cleanup_live_vars php-src/Zend/zend_execute.c:5002
    #7 0x5561c1e120e0 in zend_dispatch_try_catch_finally_helper_SPEC php-src/Zend/zend_vm_execute.h:3384
    #8 0x5561c1e127a9 in ZEND_HANDLE_EXCEPTION_SPEC_HANDLER php-src/Zend/zend_vm_execute.h:3458
    #9 0x5561c1f699c2 in execute_ex php-src/Zend/zend_vm_execute.h:110976
    #10 0x5561c1f7d33d in zend_execute php-src/Zend/zend_vm_execute.h:116055
    #11 0x5561c20f6df4 in zend_execute_script php-src/Zend/zend.c:1986
    #12 0x5561c1ae4441 in php_execute_script_ex php-src/main/main.c:2636
    #13 0x5561c1ae499e in php_execute_script php-src/main/main.c:2676
    #14 0x5561c20fcb86 in do_cli php-src/sapi/cli/php_cli.c:941
    #15 0x5561c20ff363 in do_php_cli php-src/sapi/cli/php_cli.c:1354
    #16 0x5561c20f7c3e in main php-src/sapi/cli/php_cli_main.c:18
    #17 0x7f62c13b9d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)

previously allocated by thread T0 here:
    #0 0x7f62c1b54887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x5561c1cb3901 in __zend_malloc php-src/Zend/zend_alloc.c:4071
    #2 0x5561c1cad251 in _emalloc php-src/Zend/zend_alloc.c:3042
    #3 0x5561c1fa7f1b in _zend_new_array php-src/Zend/zend_hash.c:352
    #4 0x5561c17b7576 in array_init_size php-src/Zend/zend_API.h:509
    #5 0x5561c17d8867 in zif_range php-src/ext/standard/array.c:3122
    #6 0x5561c1dfce9f in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER php-src/Zend/zend_vm_execute.h:1393
    #7 0x5561c1f69188 in execute_ex php-src/Zend/zend_vm_execute.h:110841
    #8 0x5561c1f7d33d in zend_execute php-src/Zend/zend_vm_execute.h:116055
    #9 0x5561c20f6df4 in zend_execute_script php-src/Zend/zend.c:1986
    #10 0x5561c1ae4441 in php_execute_script_ex php-src/main/main.c:2636
    #11 0x5561c1ae499e in php_execute_script php-src/main/main.c:2676
    #12 0x5561c20fcb86 in do_cli php-src/sapi/cli/php_cli.c:941
    #13 0x5561c20ff363 in do_php_cli php-src/sapi/cli/php_cli.c:1354
    #14 0x5561c20f7c3e in main php-src/sapi/cli/php_cli_main.c:18
    #15 0x7f62c13b9d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)

SUMMARY: AddressSanitizer: heap-use-after-free php-src/Zend/zend_gc.c:2302 in zend_gc_remove_root_tmpvars

To reproduce:

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

Commit:

780f4e8217b7e6afc28477b6ca12ba8efe7ba6c8

Configurations:

CC=gcc CFLAGS="-g -O1 -fsanitize=address -fno-omit-frame-pointer" LDFLAGS="-fsanitize=address" \
./configure --enable-debug --disable-shared --enable-pic --enable-mbstring --with-zlib --without-iconv

This bug was found by EyeQ, Following Dragons: Code Review-Guided Fuzzing (to appear at ICSE 2027).

PHP Version

PHP 8.7.0-dev (cli) (built: Oct 28 2026 13:03:37) (NTS DEBUG)
Copyright © The PHP Group and Contributors
Zend Engine v4.7.0-dev, Copyright © Zend by Perforce

Operating System

Ubuntu 22.04

Activity

  1. self-assigned this
    on Oct 28, 2026
  2. arnaud-lb commented on Oct 29, 2026

    @arnaud-lb
    Member

    Related: #20001

  3. added 4 commits that reference this issue on Oct 29, 2026
    7abaad3
    422cded
    7ab1c1a
    7499720
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions