Bug #80894 [Opn]: GC-related crash after using __debugInfo()
| From: | cmb@php.net | Date: | Wed, 24 Mar 2021 12:20:12 +0000 |
| Subject: | Bug #80894 [Opn]: GC-related crash after using __debugInfo() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-232962@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80894&edit=1
ID: 80894
Updated by: cmb@php.net
Reported by: tstarling@php.net
Summary: GC-related crash after using __debugInfo()
Status: Open
Type: Bug
Package: Reproducible crash
Operating System: Linux
PHP Version: 7.3Git-2021-03-22 (Git)
-Assigned To:
+Assigned To: stas
Block user comment: N
Private report: N
New Comment:
PHP-7.3 only receives security support[1], and this doesn't look
like a security issue according to our classification[2]. If it
is indeed not a security issue, and PHP-7.4+ is not affected, this
would be not a bug.
Stas, what do you think?
[1] <https://www.php.net/supported-versions.php>
[2] <https://wiki.php.net/security>
Previous Comments:
------------------------------------------------------------------------
[2021-03-22 11:36:15] tstarling@php.net
You will need to merge https://github.com/php/php-src/pull/6793 to
reproduce the bug with AddressSanitizer.
------------------------------------------------------------------------
[2021-03-22 11:35:22] tstarling@php.net
The following pull request has been associated:
Patch Name: Fix bug #80894: properly free debuginfo
On GitHub: https://github.com/php/php-src/pull/6794
Patch: https://github.com/php/php-src/pull/6794.patch
------------------------------------------------------------------------
[2021-03-22 11:28:51] tstarling@php.net
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 this bug report at https://bugs.php.net/bug.php?id=80894&edit=1