Bug #80894 [NEW]: GC-related crash after using __debugInfo()

From: Date: Mon, 22 Mar 2021 11:28:51 +0000
Subject: Bug #80894 [NEW]: GC-related crash after using __debugInfo()
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232913@lists.php.net to get a copy of this message
From: tstarling Operating system: Linux PHP version: 7.3Git-2021-03-22 (Git) Package: Reproducible crash Bug Type: Bug Bug description:GC-related crash after using __debugInfo() Description: ------------ While investigating a reproducible segfault encountered in automated testing of https://gerrit.wikimedia.org/r/c/mediawiki/core/+/672845 , I discovered that PHP 7.3's var_dump() does not correctly free the return value of the __debugInfo() method. It uses zend_hash_destroy() instead of zend_array_destroy(), causing the array to potentially remain in the GC root buffer. When the GC runs, the array is freed a second time. Compiling with AddressSanitizer helped to isolate the issue, allowing it to be demonstrated with a short test case. PHP 7.4+ is not affected due to the introduction of zend_get_properties_for(). Test script: --------------- <?php class C { public function __debugInfo() { // Clone the empty array and add it to the GC buffer $res = array_merge( [] ); return $res; } } $c = new C; var_dump( $c ); Expected result: ---------------- object(C)#1 (0) { } Actual result: -------------- object(C)#1 (0) { } ================================================================= ==914259==ERROR: AddressSanitizer: heap-use-after-free on address 0x6060000166a4 at pc 0x555556a46f9b bp 0x7fffffffac50 sp 0x7fffffffac40 READ of size 4 at 0x6060000166a4 thread T0 #0 0x555556a46f9a in gc_mark_roots /srv/php/core/Zend/zend_gc.c:976 #1 0x555556a4a928 in zend_gc_collect_cycles /srv/php/core/Zend/zend_gc.c:1473 #2 0x55555697aba2 in shutdown_executor /srv/php/core/Zend/zend_execute_API.c:293 #3 0x5555569b8c44 in zend_deactivate /srv/php/core/Zend/zend.c:1104 #4 0x55555685dfcd in php_request_shutdown /srv/php/core/main/main.c:1928 #5 0x555556c20146 in do_cli /srv/php/core/sapi/cli/php_cli.c:1167 #6 0x555556c2116e in main /srv/php/core/sapi/cli/php_cli.c:1396 #7 0x7ffff653d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) #8 0x555555a6f46d in _start (/srv/php/core/sapi/cli/php+0x51b46d) 0x6060000166a4 is located 4 bytes inside of 56-byte region [0x6060000166a0,0x6060000166d8) freed by thread T0 here: #0 0x7ffff769a7cf in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf) #1 0x55555692d553 in _efree /srv/php/core/Zend/zend_alloc.c:2516 #2 0x55555666d81a in php_var_dump /srv/php/core/ext/standard/var.c:168 #3 0x55555666dd5c in zif_var_dump /srv/php/core/ext/standard/var.c:210 #4 0x555556abb16e in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /srv/php/core/Zend/zend_vm_execute.h:649 #5 0x555556c06809 in execute_ex /srv/php/core/Zend/zend_vm_execute.h:55499 #6 0x555556c17f26 in zend_execute /srv/php/core/Zend/zend_vm_execute.h:60935 #7 0x5555569bc397 in zend_execute_scripts /srv/php/core/Zend/zend.c:1568 #8 0x5555568611b2 in php_execute_script /srv/php/core/main/main.c:2637 #9 0x555556c1ee23 in do_cli /srv/php/core/sapi/cli/php_cli.c:1000 #10 0x555556c2116e in main /srv/php/core/sapi/cli/php_cli.c:1396 #11 0x7ffff653d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) previously allocated by thread T0 here: #0 0x7ffff769abc8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8) #1 0x55555692f1e7 in __zend_malloc /srv/php/core/Zend/zend_alloc.c:2909 #2 0x55555692d3f4 in _emalloc /srv/php/core/Zend/zend_alloc.c:2502 #3 0x5555569eaec0 in _zend_new_array /srv/php/core/Zend/zend_hash.c:224 #4 0x555556514406 in php_array_merge_or_replace_wrapper /srv/php/core/ext/standard/array.c:3796 #5 0x555556514dbe in zif_array_merge /srv/php/core/ext/standard/array.c:3845 #6 0x555556abb78d in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /srv/php/core/Zend/zend_vm_execute.h:694 #7 0x555556c0683a in execute_ex /srv/php/core/Zend/zend_vm_execute.h:55503 #8 0x55555697f8c9 in zend_call_function /srv/php/core/Zend/zend_execute_API.c:756 #9 0x555556a28e02 in zend_call_method /srv/php/core/Zend/zend_interfaces.c:103 #10 0x555556a7d979 in zend_std_get_debug_info /srv/php/core/Zend/zend_object_handlers.c:155 #11 0x55555666d327 in php_var_dump /srv/php/core/ext/standard/var.c:153 #12 0x55555666dd5c in zif_var_dump /srv/php/core/ext/standard/var.c:210 #13 0x555556abb16e in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /srv/php/core/Zend/zend_vm_execute.h:649 #14 0x555556c06809 in execute_ex /srv/php/core/Zend/zend_vm_execute.h:55499 #15 0x555556c17f26 in zend_execute /srv/php/core/Zend/zend_vm_execute.h:60935 #16 0x5555569bc397 in zend_execute_scripts /srv/php/core/Zend/zend.c:1568 #17 0x5555568611b2 in php_execute_script /srv/php/core/main/main.c:2637 #18 0x555556c1ee23 in do_cli /srv/php/core/sapi/cli/php_cli.c:1000 #19 0x555556c2116e in main /srv/php/core/sapi/cli/php_cli.c:1396 #20 0x7ffff653d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) SUMMARY: AddressSanitizer: heap-use-after-free /srv/php/core/Zend/zend_gc.c:976 in gc_mark_roots Shadow bytes around the buggy address: 0x0c0c7fffac80: fd fd fd fd fd fd fd fa fa fa fa fa 00 00 00 00 0x0c0c7fffac90: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fd 0x0c0c7fffaca0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa 0x0c0c7fffacb0: 00 00 00 00 00 00 00 fa fa fa fa fa 00 00 00 00 0x0c0c7fffacc0: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fd =>0x0c0c7fffacd0: fa fa fa fa[fd]fd fd fd fd fd fd fa fa fa fa fa 0x0c0c7ffface0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fffacf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fffad00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fffad10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0c7fffad20: 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 Shadow gap: cc ==914259==ABORTING [Inferior 1 (process 914259) exited with code 01] -- Edit bug report at https://bugs.php.net/bug.php?id=80894&edit=1 -- Fix committed: https://bugs.php.net/fix.php?id=80894&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=80894&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=80894&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=80894&r=needscript Try newer version: https://bugs.php.net/fix.php?id=80894&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=80894&r=support Expected behavior: https://bugs.php.net/fix.php?id=80894&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=80894&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=80894&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=80894&r=globals PHP version support discontinued: https://bugs.php.net/fix.php?id=80894&r=phptooold Daylight Savings: https://bugs.php.net/fix.php?id=80894&r=dst IIS Stability: https://bugs.php.net/fix.php?id=80894&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=80894&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=80894&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=80894&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=80894&r=mysqlcfg

« previous php.bugs (#232913) next »