Bug #78502 [Ver]: Segmentation Fault in array_map
| From: | phofstetter at sensational dot ch | Date: | Fri, 06 Sep 2019 08:46:33 +0000 |
| Subject: | Bug #78502 [Ver]: Segmentation Fault in array_map | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-222595@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78502&edit=1
ID: 78502
User updated by: phofstetter at sensational dot ch
Reported by: phofstetter at sensational dot ch
Summary: Segmentation Fault in array_map
Status: Verified
Type: Bug
Package: Reproducible crash
Operating System: macos 10.14, Debian 10
PHP Version: 7.4.0RC1
Block user comment: N
Private report: N
New Comment:
I have bisected the issue and found
b36dbdd1dd431d1a21fdb6f2508c7c41b682466c
to be the culprit. I tried to naïvely just revert that one commit, but of course other changes
happened since then and I'm definitely not good enough to deal with the internals at this level
in order to fix the ensuing conflicts.
Previous Comments:
------------------------------------------------------------------------
[2019-09-06 08:05:54] nikic@php.net
Looks like an icall retval slot ends up pointing into the execute_data frame and clobbers func.
------------------------------------------------------------------------
[2019-09-06 06:45:39] phofstetter at sensational dot ch
one last update: This happens independently of whether opcache is loaded or not.
------------------------------------------------------------------------
[2019-09-06 06:41:05] phofstetter at sensational dot ch
On Debian 10, the attached test script also crashes with a debugger attached. Here's the
backtrace:
(gdb) run segv.php
Starting program: /opt/php/7.4/bin/php segv.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000555555a881fb in zend_call_function (fci=fci@entry=0x7fffffffa8a0,
fci_cache=fci_cache@entry=0x7fffffffa880)
at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_execute_API.c:681
681 } else if (EG(current_execute_data)->func &&
(gdb) bt
#0 0x0000555555a881fb in zend_call_function (fci=fci@entry=0x7fffffffa8a0,
fci_cache=fci_cache@entry=0x7fffffffa880)
at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_execute_API.c:681
#1 0x00005555559c6428 in zif_array_map (execute_data=<optimized out>,
return_value=0x7ffff4013350)
at /home/crazyhat/downloads/php-7.4.0RC1/ext/standard/array.c:6203
#2 0x0000555555b10820 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at
/home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:1323
#3 execute_ex (ex=0x7fffffffa8a0) at
/home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:53461
#4 0x0000555555a88826 in zend_call_function (fci=fci@entry=0x7fffffffaaf0, fci_cache=<optimized
out>, fci_cache@entry=0x7fffffffaad0)
at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_execute_API.c:816
#5 0x00005555559c6428 in zif_array_map (execute_data=<optimized out>,
return_value=0x7ffff4013170)
at /home/crazyhat/downloads/php-7.4.0RC1/ext/standard/array.c:6203
#6 0x0000555555b10820 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at
/home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:1323
#7 execute_ex (ex=0x7fffffffa8a0) at
/home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:53461
#8 0x0000555555b16a63 in zend_execute (op_array=0x7ffff407c2a0, return_value=<optimized out>)
at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:57561
#9 0x0000555555a964c4 in zend_execute_scripts (type=type@entry=8, retval=0x7ffff40130b0,
retval@entry=0x0, file_count=file_count@entry=3)
at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend.c:1663
#10 0x0000555555a39fa0 in php_execute_script (primary_file=<optimized out>) at
/home/crazyhat/downloads/php-7.4.0RC1/main/main.c:2619
#11 0x0000555555b18a66 in do_cli (argc=2, argv=0x55555677a5d0) at
/home/crazyhat/downloads/php-7.4.0RC1/sapi/cli/php_cli.c:961
#12 0x0000555555794239 in main (argc=2, argv=0x55555677a5d0) at
/home/crazyhat/downloads/php-7.4.0RC1/sapi/cli/php_cli.c:1352
------------------------------------------------------------------------
[2019-09-06 06:33:17] phofstetter at sensational dot ch
Also happens on Debian 10
------------------------------------------------------------------------
[2019-09-06 06:12:37] phofstetter at sensational dot ch
Description:
------------
The test script attached to this bug report will cause a segmenation fault, however, unfortunately,
it doesn't happen when a debubgger is attached(??)
pilif@celes:~| â php --version
PHP 7.4.0RC1 (cli) (built: Sep 6 2019 07:35:43) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies
pilif@celes:~| â php segv.php
[1] 73522 segmentation fault php segv.php
pilif@celes:~| â
Test script:
---------------
<?php
$tree = [
'name' => 'a',
'quant' => 1,
'children' => [
['name' => 'b', 'quant' => 1],
['name' => 'c', 'quant' => 1, 'children' =>
[
['name' => 'd', 'quant' => 1],
]],
],
];
function tree_map($tree, $recursive_attr, closure $callback){
if(isset($tree[$recursive_attr])){
$tree[$recursive_attr] = array_map(function($c) use($recursive_attr, $callback){
return tree_map($c, $recursive_attr, $callback);
}, $tree[$recursive_attr]);
}
return $callback($tree);
}
tree_map($tree, 'children', function ($node) {});
Expected result:
----------------
no segfault
Actual result:
--------------
segfault. My attempts at getting a proper backtrace were foiled by this not crashing when e debugger
is attached.
However, a slightly more complicated version of the script produced the following trace in lldb:
pilif@celes:~| â lldb php
(lldb) target create "php"
Current executable set to 'php' (x86_64).
(lldb) run segv.php
Process 96419 launched: '/usr/local/bin/php' (x86_64)
Process 96419 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
frame #0: 0x00000001003c2a3c php`zend_leave_helper_SPEC + 60
php`zend_leave_helper_SPEC:
-> 0x1003c2a3c <+60>: decl (%rdi)
0x1003c2a3e <+62>: je 0x1003c2a66 ; <+102>
0x1003c2a40 <+64>: movl 0x4(%rdi), %eax
0x1003c2a43 <+67>: cmpl $0xa, %eax
Target 0: (php) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
* frame #0: 0x00000001003c2a3c php`zend_leave_helper_SPEC + 60
frame #1: 0x000000010037f4ff php`execute_ex + 35
frame #2: 0x0000000100335102 php`zend_call_function + 1230
frame #3: 0x0000000100256cc0 php`zif_array_map + 448
frame #4: 0x00000001003b0365 php`ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER + 80
frame #5: 0x000000010037f4ff php`execute_ex + 35
frame #6: 0x000000010037f6b7 php`zend_execute + 352
frame #7: 0x0000000100342981 php`zend_execute_scripts + 338
frame #8: 0x00000001002eb7bc php`php_execute_script + 482
frame #9: 0x00000001003c86fb php`do_cli + 3893
frame #10: 0x00000001003c7659 php`main + 1229
frame #11: 0x00007fff644192a5 libdyld.dylib`start + 1
(lldb)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78502&edit=1