Skip to content

Use-after-free in SplHeap #16337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chibinz opened this issue Oct 10, 2024 · 0 comments
Closed

Use-after-free in SplHeap #16337

chibinz opened this issue Oct 10, 2024 · 0 comments

Comments

@chibinz
Copy link

chibinz commented Oct 10, 2024

Description

The following code:

<?php

class C {
    function __toString() {
        global $heap;
        $heap->extract();
        return "0";
    }
}

$heap = new SplMinHeap;
for ($i = 0; $i < 100; $i++) {
    $heap->insert((string) $i);
}
$heap->insert(new C);

Resulted in this output:

=================================================================
==315583==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000028b10 at pc 0x55da198e2595 bp 0x7ffe7f223380 sp 0x7ffe7f223378
READ of size 4 at 0x603000028b10 thread T0
    #0 0x55da198e2594 in zend_gc_delref /tmp/php-afl/Zend/zend_types.h:1346:2
    #1 0x55da198e2594 in i_zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.h:44:8
    #2 0x55da198e2594 in zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.c:84:2
    #3 0x55da18c100d9 in spl_ptr_heap_destroy /tmp/php-afl/ext/spl/spl_heap.c:381:3
    #4 0x55da18c100d9 in spl_heap_object_free_storage /tmp/php-afl/ext/spl/spl_heap.c:400:2
    #5 0x55da1985594f in zend_objects_store_del /tmp/php-afl/Zend/zend_objects_API.c:194:4
    #6 0x55da198e3b02 in rc_dtor_func /tmp/php-afl/Zend/zend_variables.c:57:2
    #7 0x55da198e3b02 in i_zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.h:45:4
    #8 0x55da198e3b02 in zend_reference_destroy /tmp/php-afl/Zend/zend_variables.c:74:2
    #9 0x55da198e2523 in rc_dtor_func /tmp/php-afl/Zend/zend_variables.c:57:2
    #10 0x55da198e2523 in i_zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.h:45:4
    #11 0x55da198e2523 in zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.c:84:2
    #12 0x55da1971178f in _zend_hash_del_el_ex /tmp/php-afl/Zend/zend_hash.c:1487:3
    #13 0x55da1971178f in _zend_hash_del_el /tmp/php-afl/Zend/zend_hash.c:1514:2
    #14 0x55da1972112d in zend_hash_graceful_reverse_destroy /tmp/php-afl/Zend/zend_hash.c:2039:4
    #15 0x55da193e3f18 in zend_shutdown_executor_values /tmp/php-afl/Zend/zend_execute_API.c:287:3
    #16 0x55da193e84a5 in shutdown_executor /tmp/php-afl/Zend/zend_execute_API.c:442:2
    #17 0x55da19901bb9 in zend_deactivate /tmp/php-afl/Zend/zend.c:1341:2
    #18 0x55da18fce440 in php_request_shutdown /tmp/php-afl/main/main.c:1950:2
    #19 0x55da1991357b in do_cli /tmp/php-afl/sapi/cli/php_cli.c:1106:3
    #20 0x55da1990e441 in main /tmp/php-afl/sapi/cli/php_cli.c:1310:18
    #21 0x7f7c55629d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
    #22 0x7f7c55629e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
    #23 0x55da18202a24 in _start (/workspaces/TriFuzz/targets/php-afl/bin/php+0x402a24)

0x603000028b10 is located 0 bytes inside of 32-byte region [0x603000028b10,0x603000028b30)
freed by thread T0 here:
    #0 0x55da18287342 in free /opt/llvm-15-build/llvm-15.x/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
    #1 0x55da198e2523 in rc_dtor_func /tmp/php-afl/Zend/zend_variables.c:57:2
    #2 0x55da198e2523 in i_zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.h:45:4
    #3 0x55da198e2523 in zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.c:84:2
    #4 0x55da18c100d9 in spl_ptr_heap_destroy /tmp/php-afl/ext/spl/spl_heap.c:381:3
    #5 0x55da18c100d9 in spl_heap_object_free_storage /tmp/php-afl/ext/spl/spl_heap.c:400:2
    #6 0x55da1985594f in zend_objects_store_del /tmp/php-afl/Zend/zend_objects_API.c:194:4
    #7 0x55da198e3b02 in rc_dtor_func /tmp/php-afl/Zend/zend_variables.c:57:2
    #8 0x55da198e3b02 in i_zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.h:45:4
    #9 0x55da198e3b02 in zend_reference_destroy /tmp/php-afl/Zend/zend_variables.c:74:2
    #10 0x55da198e2523 in rc_dtor_func /tmp/php-afl/Zend/zend_variables.c:57:2
    #11 0x55da198e2523 in i_zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.h:45:4
    #12 0x55da198e2523 in zval_ptr_dtor /tmp/php-afl/Zend/zend_variables.c:84:2
    #13 0x55da1971178f in _zend_hash_del_el_ex /tmp/php-afl/Zend/zend_hash.c:1487:3
    #14 0x55da1971178f in _zend_hash_del_el /tmp/php-afl/Zend/zend_hash.c:1514:2
    #15 0x55da1972112d in zend_hash_graceful_reverse_destroy /tmp/php-afl/Zend/zend_hash.c:2039:4
    #16 0x55da193e3f18 in zend_shutdown_executor_values /tmp/php-afl/Zend/zend_execute_API.c:287:3
    #17 0x55da193e84a5 in shutdown_executor /tmp/php-afl/Zend/zend_execute_API.c:442:2
    #18 0x55da19901bb9 in zend_deactivate /tmp/php-afl/Zend/zend.c:1341:2
    #19 0x55da18fce440 in php_request_shutdown /tmp/php-afl/main/main.c:1950:2
    #20 0x55da1991357b in do_cli /tmp/php-afl/sapi/cli/php_cli.c:1106:3
    #21 0x55da1990e441 in main /tmp/php-afl/sapi/cli/php_cli.c:1310:18
    #22 0x7f7c55629d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)

previously allocated by thread T0 here:
    #0 0x55da182875ee in malloc /opt/llvm-15-build/llvm-15.x/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3
    #1 0x55da19222cee in __zend_malloc /tmp/php-afl/Zend/zend_alloc.c:3280:14
    #2 0x55da1987f9c1 in zend_string_alloc /tmp/php-afl/Zend/zend_string.h:176:36
    #3 0x55da1987f9c1 in zend_string_init /tmp/php-afl/Zend/zend_string.h:198:21
    #4 0x55da1987f9c1 in zend_long_to_str /tmp/php-afl/Zend/zend_operators.c:3425:23
    #5 0x55da1987f9c1 in __zval_get_string_func /tmp/php-afl/Zend/zend_operators.c:1023:11
    #6 0x55da1950f1f9 in zval_get_string /tmp/php-afl/Zend/zend_operators.h:327:79
    #7 0x55da1950f1f9 in ZEND_CAST_SPEC_CV_HANDLER /tmp/php-afl/Zend/zend_vm_execute.h:40945:4
    #8 0x55da194206f0 in execute_ex /tmp/php-afl/Zend/zend_vm_execute.h:58554:7
    #9 0x55da19421507 in zend_execute /tmp/php-afl/Zend/zend_vm_execute.h:64206:2
    #10 0x55da19908b34 in zend_execute_script /tmp/php-afl/Zend/zend.c:1928:3
    #11 0x55da18fd559e in php_execute_script_ex /tmp/php-afl/main/main.c:2574:13
    #12 0x55da199126fc in do_cli /tmp/php-afl/sapi/cli/php_cli.c:935:5
    #13 0x55da1990e441 in main /tmp/php-afl/sapi/cli/php_cli.c:1310:18
    #14 0x7f7c55629d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)

SUMMARY: AddressSanitizer: heap-use-after-free /tmp/php-afl/Zend/zend_types.h:1346:2 in zend_gc_delref
Shadow bytes around the buggy address:
  0x0c067fffd110: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c067fffd120: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
  0x0c067fffd130: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
  0x0c067fffd140: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c067fffd150: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
=>0x0c067fffd160: fa fa[fd]fd fd fd fa fa fd fd fd fd fa fa fd fd
  0x0c067fffd170: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x0c067fffd180: fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 00 01
  0x0c067fffd190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffd1a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffd1b0: 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
==315583==ABORTING

But I expected this output instead:

no crash

PHP Version

PHP 8.4.0-dev

Operating System

No response

nielsdos added a commit to nielsdos/php-src that referenced this issue Oct 10, 2024
We introduce a new flag to indicate when a heap or priority queue is
write-locked. In principle we could've used SPL_HEAP_CORRUPTED too, but
that won't be descriptive to users (and it's a lie too).
@nielsdos nielsdos linked a pull request Oct 10, 2024 that will close this issue
nielsdos added a commit that referenced this issue Oct 12, 2024
* PHP-8.2:
  Fix GH-16337: Use-after-free in SplHeap
nielsdos added a commit that referenced this issue Oct 12, 2024
* PHP-8.3:
  Add missing hierarchy checks to replaceChild
  Fix GH-16337: Use-after-free in SplHeap
nielsdos added a commit that referenced this issue Oct 12, 2024
* PHP-8.4:
  Add missing hierarchy checks to replaceChild
  Fix GH-16337: Use-after-free in SplHeap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants