php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70262 Accessing array crashes PHP 7.0beta3
Submitted: 2015-08-13 18:14 UTC Modified: 2015-08-16 07:02 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: pavel dot kouril at hotmail dot com Assigned: laruence
Status: Closed Package: Reproducible crash
PHP Version: 7.0.0beta3 OS: Windows, Linux
Private report: No CVE-ID:
 [2015-08-13 18:14 UTC] pavel dot kouril at hotmail dot com
Description:
------------
When running the script www/index.php, the PHP crashes with SIGSEGV without logging any error to error log.

The issue is in \Nette\DI\Helpers::autowireArguments on the line 91 when accessing the $arguments array. The array is malformed and crashes the whole PHP (var_dump reveals that the array is array(1953459822) instead of expected array(2)).

Issue happens on both Windows and Linux machines. PHP crashed when I tried to run it with any of these 3 methods:

- php www\index.php
- php -S localhost:3333 -t www
- via FastCGI IIS handler

I tried to isolate the issue as much as possible, so hopefully it will be enough.

The script (and original project where I stumbled upon the issue) work fine on PHP 5.6.

Test script:
---------------
https://github.com/pavelkouril/php7-sigsegv


Just cloning it and running it via any of those 3 aforementioned methods should reproduce the issue.


Actual result:
--------------
Starting program: /usr/bin/php -n www/index.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.
0x0000000000c152b9 in zend_hash_index_find_bucket (ht=0x7fffea6fac00, h=0) at Zend/zend_hash.c:464
464		idx = HT_HASH_EX(arData, nIndex);

bt:

#0  0x0000000000c152b9 in zend_hash_index_find_bucket (ht=0x7fffea6fac00, h=0) at Zend/zend_hash.c:464
#1  0x0000000000c14aa9 in zend_hash_index_exists (ht=0x7fffea6fac00, h=0) at Zend/zend_hash.c:1938
#2  0x00000000009d0684 in zif_array_key_exists (execute_data=0x7fffeac17710, return_value=0x7fffeac172e0) at ext/standard/array.c:4978
#3  0x0000000000cb61f0 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7fffeac170f0) at Zend/zend_vm_execute.h:706
#4  0x0000000000c5b084 in execute_ex (ex=0x7fffeac14cc0) at Zend/zend_vm_execute.h:409
#5  0x0000000000bdf2ba in zend_call_function (fci=0x7fffffffa3b0, fci_cache=0x7fffffffa388) at Zend/zend_execute_API.c:852
#6  0x00000000009d5178 in zif_call_user_func_array (execute_data=0x7fffeac14c40, return_value=0x7fffeac14b40) at ext/standard/basic_functions.c:4809
#7  0x0000000000cb61f0 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7fffeac14a30) at Zend/zend_vm_execute.h:706
#8  0x0000000000c5b084 in execute_ex (ex=0x7fffeac14030) at Zend/zend_vm_execute.h:409
#9  0x0000000000c5b1da in zend_execute (op_array=0x7fffeac82000, return_value=0x0) at Zend/zend_vm_execute.h:450
#10 0x0000000000bfae7d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at Zend/zend.c:1404
#11 0x0000000000b571bd in php_execute_script (primary_file=0x7fffffffdfd8) at main/main.c:2475
#12 0x0000000000ce305c in do_cli (argc=3, argv=0x1637140) at sapi/cli/php_cli.c:971
#13 0x0000000000ce1f82 in main (argc=3, argv=0x1637140) at sapi/cli/php_cli.c:1338



bt full:

#0  0x0000000000c152b9 in zend_hash_index_find_bucket (ht=0x7fffea6fac00, h=0) at Zend/zend_hash.c:464
        nIndex = 0
        idx = 4294942816
        p = 0x125b7d0
        arData = 0x1e
#1  0x0000000000c14aa9 in zend_hash_index_exists (ht=0x7fffea6fac00, h=0) at Zend/zend_hash.c:1938
        p = 0x1
#2  0x00000000009d0684 in zif_array_key_exists (execute_data=0x7fffeac17710, return_value=0x7fffeac172e0) at ext/standard/array.c:4978
        key = 0x7fffeac17770
        array = 0x7fffea6fac00
#3  0x0000000000cb61f0 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7fffeac170f0) at Zend/zend_vm_execute.h:706
        opline = 0x7fffea6013a0
        call = 0x7fffeac17710
        fbc = 0x16a3490
        ret = 0x7fffeac172e0
#4  0x0000000000c5b084 in execute_ex (ex=0x7fffeac14cc0) at Zend/zend_vm_execute.h:409
        ret = 0
        execute_data = 0x7fffeac170f0
#5  0x0000000000bdf2ba in zend_call_function (fci=0x7fffffffa3b0, fci_cache=0x7fffffffa388) at Zend/zend_execute_API.c:852
        call_via_handler = 0
        i = 1
        calling_scope = 0x7fffeac06428
        call = 0x7fffeac14cc0
        dummy_execute_data = {opline = 0x7fffeac14ca0, call = 0x7fffffffa3c0, return_value = 0x7fffffffa350, func = 0x7fffead2d608, This = {value = {lval = 140737133073960, dval = 6.9533382546031507e-310, 
              counted = 0x7fffead2d628, str = 0x7fffead2d628, arr = 0x7fffead2d628, obj = 0x7fffead2d628, res = 0x7fffead2d628, ref = 0x7fffead2d628, ast = 0x7fffead2d628, zv = 0x7fffead2d628, 
              ptr = 0x7fffead2d628, ce = 0x7fffead2d628, func = 0x7fffead2d628, ww = {w1 = 3939685928, w2 = 32767}}, u1 = {v = {type = 40 '(', type_flags = 214 '\326', const_flags = 210 '\322', 
                reserved = 234 '\352'}, type_info = 3939685928}, u2 = {var_flags = 32767, next = 32767, cache_slot = 32767, lineno = 32767, num_args = 32767, fe_pos = 32767, fe_iter_idx = 32767}}, 
          run_time_cache = 0x2eac00000, literals = 0x7fffead44b20, called_scope = 0x7fffead2d608, prev_execute_data = 0x7fffeac14cb0, symbol_table = 0x0}
        fci_cache_local = {initialized = 96 '`', function_handler = 0x7fffead2d608, calling_scope = 0x7fffead44b10, called_scope = 0x1c07ead4d540, object = 0x7fffead4d300}
        func = 0x7fffeac06fd0
        orig_scope = 0x7fffeac11e90
#6  0x00000000009d5178 in zif_call_user_func_array (execute_data=0x7fffeac14c40, return_value=0x7fffeac14b40) at ext/standard/basic_functions.c:4809
        params = 0x7fffeac14cb0
        retval = {value = {lval = 13419062, dval = 6.6298975336137295e-317, counted = 0xccc236 <_get_zval_ptr_tmp+54>, str = 0xccc236 <_get_zval_ptr_tmp+54>, arr = 0xccc236 <_get_zval_ptr_tmp+54>, 
            obj = 0xccc236 <_get_zval_ptr_tmp+54>, res = 0xccc236 <_get_zval_ptr_tmp+54>, ref = 0xccc236 <_get_zval_ptr_tmp+54>, ast = 0xccc236 <_get_zval_ptr_tmp+54>, zv = 0xccc236 <_get_zval_ptr_tmp+54>, 
            ptr = 0xccc236 <_get_zval_ptr_tmp+54>, ce = 0xccc236 <_get_zval_ptr_tmp+54>, func = 0xccc236 <_get_zval_ptr_tmp+54>, ww = {w1 = 13419062, w2 = 0}}, u1 = {v = {type = 0 '\000', 
              type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 0}, u2 = {var_flags = 32767, next = 32767, cache_slot = 32767, lineno = 32767, num_args = 32767, fe_pos = 32767, 
            fe_iter_idx = 32767}}
        fci = {size = 72, function_table = 0x7fffeac06468, function_name = {value = {lval = 140737133204224, dval = 6.9533382610390474e-310, counted = 0x7fffead4d300, str = 0x7fffead4d300, 
              arr = 0x7fffead4d300, obj = 0x7fffead4d300, res = 0x7fffead4d300, ref = 0x7fffead4d300, ast = 0x7fffead4d300, zv = 0x7fffead4d300, ptr = 0x7fffead4d300, ce = 0x7fffead4d300, 
              func = 0x7fffead4d300, ww = {w1 = 3939816192, w2 = 32767}}, u1 = {v = {type = 7 '\a', type_flags = 28 '\034', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 7175}, u2 = {var_flags = 2, 
              next = 2, cache_slot = 2, lineno = 2, num_args = 2, fe_pos = 2, fe_iter_idx = 2}}, symbol_table = 0x0, retval = 0x7fffffffa3f8, params = 0x7fffead44b10, object = 0x7fffeac770c0, 
          no_separation = 1 '\001', param_count = 1}
        fci_cache = {initialized = 1 '\001', function_handler = 0x7fffeac06fd0, calling_scope = 0x7fffeac06428, called_scope = 0x7fffeac06428, object = 0x7fffeac770c0}
#7  0x0000000000cb61f0 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7fffeac14a30) at Zend/zend_vm_execute.h:706
        opline = 0x7fffeaca0cc0
        call = 0x7fffeac14c40
        fbc = 0x1646360
        ret = 0x7fffeac14b40
#8  0x0000000000c5b084 in execute_ex (ex=0x7fffeac14030) at Zend/zend_vm_execute.h:409
        ret = 0
        execute_data = 0x7fffeac14a30
#9  0x0000000000c5b1da in zend_execute (op_array=0x7fffeac82000, return_value=0x0) at Zend/zend_vm_execute.h:450
        execute_data = 0x7fffeac14030
#10 0x0000000000bfae7d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at Zend/zend.c:1404
        files = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fffffffa760, reg_save_area = 0x7fffffffa5f0}}
        i = 1
        file_handle = 0x7fffffffdfd8
        op_array = 0x7fffeac82000
#11 0x0000000000b571bd in php_execute_script (primary_file=0x7fffffffdfd8) at main/main.c:2475
        realfile = "/tmp/sbx/www/index.php\000\000\000\000\000\000\005\000\000\000\005\000\000\200\001\000\000\000\000\000\300\352\377\177\000\000\060\020\000\000\000\000\000\000\060\020\300\352\377\177\000\000@\000\300\352\377\177\000\000@\020\300\352\377\177\000\000p\271\377\377\377\177\000\000\264\341\273\000\000\000\000\000\000\000\000\000\377\177\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\060\000\000\000\000\000\000\000@\000\300\352\377\177\000\000\t\000\000\000\000\000\000\000@\020\300\352\377\177\000\000\t\000\000\000\000\000\000\000\060\020\300\352\377\177", '\000' <repeats 18 times>, "\030 \300\352\377\177\000\000\000 \300\352\377\177\000\000"...
        __orig_bailout = 0x7fffffffde80
        __bailout = {{__jmpbuf = {0, -631657247990433424, 4872752, 140737488347920, 0, 0, -631657246482581136, 631657890259450224}, __mask_was_saved = 0, __saved_mask = {__val = {567, 0, 0, 4294953376, 0, 1, 
                2439185277344, 19280726, 2430951489536, 19280726, 2426656522240, 19280726, 4436713893059, 140737131847792, 140737488341568, 140737488341424}}}}
        prepend_file_p = 0x0
        append_file_p = 0x0
        prepend_file = {handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, buf = 0x0, old_handle = 0x0, old_closer = 0x0}, reader = 0x0, fsizer = 0x0, 
              closer = 0x0}}, filename = 0x0, opened_path = 0x0, type = ZEND_HANDLE_FILENAME, free_filename = 0 '\000'}
        append_file = {handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, buf = 0x0, old_handle = 0x0, old_closer = 0x0}, reader = 0x0, fsizer = 0x0, 
              closer = 0x0}}, filename = 0x0, opened_path = 0x0, type = ZEND_HANDLE_FILENAME, free_filename = 0 '\000'}
        old_cwd = 0x7fffffffa760 ""
        use_heap = 0 '\000'
        retval = 0
#12 0x0000000000ce305c in do_cli (argc=3, argv=0x1637140) at sapi/cli/php_cli.c:971
        __orig_bailout = 0x7fffffffe100
        __bailout = {{__jmpbuf = {0, -631657248751699600, 4872752, 140737488347920, 0, 0, -631657248013502096, 631657849590430064}, __mask_was_saved = 0, __saved_mask = {__val = {0, 0, 16, 19164403, 19164448, 
                19164479, 19164488, 19164512, 19014487, 19014508, 19164525, 19164545, 19164562, 19166059, 19164583, 19164597}}}}
        c = -1
        file_handle = {handle = {fd = -356028400, fp = 0x7fffeac77010, stream = {handle = 0x7fffeac77010, isatty = 0, mmap = {len = 127, pos = 0, map = 0x7ffff7fcf000, 
                buf = 0x7ffff7fcf000 <error: Cannot access memory at address 0x7ffff7fcf000>, old_handle = 0x17d6430, old_closer = 0xc26e40 <zend_stream_stdio_closer>}, 
              reader = 0xc26e00 <zend_stream_stdio_reader>, fsizer = 0xc26e80 <zend_stream_stdio_fsizer>, closer = 0xc27100 <zend_stream_mmap_closer>}}, filename = 0x1608f20 "www/index.php", opened_path = 0x0, 
          type = ZEND_HANDLE_MAPPED, free_filename = 0 '\000'}
        behavior = 1
        reflection_what = 0x0
        request_started = 1
        exit_status = 0
        php_optarg = 0x0
        orig_optarg = 0x0
        php_optind = 3
        orig_optind = 1
        exec_direct = 0x0
        exec_run = 0x0
        exec_begin = 0x0
        exec_end = 0x0
        arg_free = 0x1608f20 "www/index.php"
        arg_excp = 0x1637150
        script_file = 0x1608f20 "www/index.php"
        translated_path = 0x17d67b0 "/tmp/sbx/www/index.php"
        interactive = 0
        lineno = 1
        param_error = 0x0
        hide_argv = 0
#13 0x0000000000ce1f82 in main (argc=3, argv=0x1637140) at sapi/cli/php_cli.c:1338
        __orig_bailout = 0x0
        __bailout = {{__jmpbuf = {0, -631657248804128400, 4872752, 140737488347920, 0, 0, -631657248749602448, 631657850051148144}, __mask_was_saved = 0, __saved_mask = {__val = {140737354130656, 
                140737488347536, 8329162840, 140737354129800, 140737488347520, 4591464, 4131212846, 4294967295, 140733193388096, 140737223856632, 140737353826304, 140733193388098, 16, 140733193388096, 2, 
                140733193388125}}}}
        c = -1
        exit_status = 0
        module_started = 1
        sapi_started = 1
        php_optarg = 0x0
        php_optind = 2
        use_extended_info = 0
        ini_path_override = 0x0
        ini_entries = 0x1637390 "html_errors=0\nregister_argc_argv=1\nimplicit_flush=1\noutput_buffering=0\nmax_execution_time=0\nmax_input_time=-1\n"
        ini_entries_len = 110
        ini_ignore = 1
        sapi_module = 0x15dc7d0 <cli_sapi_module>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-08-15 07:38 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2015-08-15 07:38 UTC] laruence@php.net
-Status: Assigned +Status: Open
 [2015-08-15 11:26 UTC] laruence@php.net
This was really a tough one to figure out the root cause :<

after all, I finally get the reason, and made a simple reproduce case:

<?php

class C {
    public $arguments;
    public function __construct($arg) {
        $this->arguments = $arg;
    }
}

function & a(&$arg) {
    $c = new C($arg);
    $arg[] = $c;
    return $c;
}

function c($arr) {
    a($arr)->arguments[0] = "bad";
}

$arr = array();
$arr[] = "foo";
$arr[] = "bar";
c($arr);
var_dump($arr);
?>

and a fix might be: https://gist.github.com/laruence/848e69d0a43846b61d26

all tests is passed....
 [2015-08-15 15:25 UTC] pavel dot kouril at hotmail dot com
I compiled PHP on Windows with your change and the application now works - thanks a lot!
 [2015-08-15 15:37 UTC] bugs dot php dot net at majkl578 dot cz
Hi laruence,

the original repro script (the php7-sigsegv repo) crashed with a regular sigsegv while your repro script ends prematurely for me (7.0.0beta3 DEBUG without your patch) with the following assert:
php: Zend/zend_gc.c:226: void gc_possible_root(zend_refcounted *): Assertion `((zend_refcounted*)(ref))->u.v.type == 7 || ((zend_refcounted*)(ref))->u.v.type == 8' failed.

Anyway, your patch fixed both. :)

Thanks for your awesome work, these issues are always PITA...
 [2015-08-16 07:02 UTC] laruence@php.net
yes, they behavior different result(double free result undefined behavior), but they have the both same root cause.. ;)

I need find out the root cause first, then can according to that made a simpler reproduce case..
 [2015-08-17 09:58 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ce89fd9758fffd6c4bffca130829734ac3fca8ec
Log: Fixed bug #70262 (Accessing array crashes PHP 7.0beta3)
 [2015-08-17 09:58 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2015-08-17 12:09 UTC] bugs dot php dot net at majkl578 dot cz
Hi,

I'm afraid the original issue has not been fixed by ce89fd9758.

I recompiled master with this commit and I am not seeing crashes with Laruence's code, but I am still getting segfaults in zend_hash_index_find_bucket with the original repro script (https://github.com/pavelkouril/php7-sigsegv). :(
 [2015-08-18 16:24 UTC] ab@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ce89fd9758fffd6c4bffca130829734ac3fca8ec
Log: Fixed bug #70262 (Accessing array crashes PHP 7.0beta3)
 [2016-07-20 11:37 UTC] davey@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ce89fd9758fffd6c4bffca130829734ac3fca8ec
Log: Fixed bug #70262 (Accessing array crashes PHP 7.0beta3)
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC