php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79209 Free a potentially controllable pointer in zend_hash_packed_to_hash
Submitted: 2020-02-01 18:56 UTC Modified: 2020-02-04 14:02 UTC
From: changochen1 at gmail dot com Assigned:
Status: Analyzed Package: Scripting Engine problem
PHP Version: master-Git-2020-02-01 (Git) OS: ALL
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: changochen1 at gmail dot com
New email:
PHP Version: OS:

 

 [2020-02-01 18:56 UTC] changochen1 at gmail dot com
Description:
------------
Running the test script with asan built, we found that it crashed with 2 errors:
1. AddressSanitizer: memcpy-param-overlap
2. AddressSanitizer: attempting free on address which was not malloc()-ed

We believe the root cause is the same.

The php version is PHP 8.0.0-dev (cli) (built: Jan 31 2020 21:52:09) ( NTS ), master branch of git.

The script is run by "php -f poc.php". The script is reduced by C-reduced so that it might look a little messy.

Here's the stack dump of memcpy overlap:
===
=================================================================
==4309==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x7f1a2165cf40,0x7f1a2165cfc0) and [0x7f1a2165cf08, 0x7f1a2165cf88) overlap
    #0 0x7f1a27c8f662 in __asan_memcpy (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8c662)
    #1 0xe7eb9e in zend_hash_packed_to_hash (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xe7eb9e)
    #2 0xe85621 in zend_hash_add_new (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xe85621)
    #3 0xfb7822 in zend_fetch_dimension_address_inner_W (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xfb7822)
    #4 0x114224b in ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x114224b)
    #5 0x12659c7 in execute_ex (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x12659c7)
    #6 0xdf5a2f in zend_call_function (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xdf5a2f)
    #7 0xdf3145 in _call_user_function_ex (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xdf3145)
    #8 0xe418a0 in zend_error_va_list (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xe418a0)
    #9 0xe427b5 in zend_error (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xe427b5)
    #10 0xfa32f3 in zval_undefined_cv (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xfa32f3)
    #11 0xfa33ce in _zval_undefined_op2 (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xfa33ce)
    #12 0xfe9238 in zend_is_smaller_or_equal_helper_SPEC (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xfe9238)
    #13 0x105a4a3 in ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x105a4a3)
    #14 0x12552a2 in execute_ex (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x12552a2)
    #15 0xdf5a2f in zend_call_function (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xdf5a2f)
    #16 0xe6de12 in zend_fcall_info_call (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xe6de12)
    #17 0xce8f9b in php_output_handler_op (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xce8f9b)
    #18 0xcea7df in php_output_stack_pop (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xcea7df)
    #19 0xce426e in php_output_end_all (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xce426e)
    #20 0xca8df5 in php_request_shutdown (/home/rxz226/php-src/bld_asan/sapi/cli/php+0xca8df5)
    #21 0x1281d33 in do_cli (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x1281d33)
    #22 0x1282acb in main (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x1282acb)
    #23 0x7f1a26aa182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #24 0x428a78 in _start (/home/rxz226/php-src/bld_asan/sapi/cli/php+0x428a78)
===

Test script:
---------------
<?@ unlink ( $GLOBALS  & in_array ( in_array ( print_r ( 2 , )    , array () , ( [] <= $a [ $i = strtoupper ( $$a [ $i = ( $a   <= define ( $f2 , ( [] <= ob_start ( function () {
            if ( [] . $obj = new stdClass < in_array (  [ var_dump ( var_dump ( $a [ $i = strtoupper ( $a   <= strtoupper ( ( ( set_error_handler ( function () {
           func_get_args ( func_get_arg ( 1 ) , var_dump ( $a   <= ( $a   <= $a   )   ) > strtoupper ( $$a [ $i = strtoupper ( $a   <= ( strtoupper ( strtoupper ( set_error_handler ( function () {
  }
          ) <= $a   )    <= $a   )   <= $a  [ $b [ $i = strtoupper ( $a [ $i = ( ( strtoupper ( $a   <= ( $a [ $i = ( $a   <= ( ( ( set_error_handler ( function () {
         unset ( $GLOBALS ) ;
         ( ( $$a   ) [ $GLOBALS  [ strtoupper ( [] <= $a   ) [ $value ] =  array ( array ( $$b [ 3 ] = 2 => set_error_handler ( $k ) , ) , )  ] = 1 ]   ) ;
         }
          , ) <= $a   )   <= $a [ ++ fopen ( $f2 , ( [] <= ob_start ( $GLOBALS [ ( $filename ) ] = $b , )   )  , $i = include_once 0 )  [] ]  )   <= a   )    ) ]  )  ) == print_r  ) ) ]  <= strtoupper     ) ] ] )    ) ]     ) ) ;
           }
            , ) <= $a   )    <= a   )   <= a   )    ) ]  ++ ) ) ]  ,  ) ) ;
             }
              )   )  , $i = 0 )    ) ] ) ]  ) ) ,  ) ) ;


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-02-01 19:40 UTC] stas@php.net
-Type: Security +Type: Bug -Package: CGI/CLI related +Package: Scripting Engine problem
 [2020-02-01 19:45 UTC] changochen1 at gmail dot com
Hi, 

Could you identify the reason that why this is not related to security? Since these memory corruption issues are severe issues from a security prospective. Your help would be appreciated. Thanks.
 [2020-02-01 23:40 UTC] changochen1 at gmail dot com
Got it. Thanks!
 [2020-02-04 13:55 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2020-02-04 13:55 UTC] nikic@php.net
php-fuzzer-execute -minimize_crash=1 produced the following reduction:

<?set_error_handler(function(){unset($GLOBALS);})[(($GLOBALS=$b))];

Or for our sake:

<?php
set_error_handler(function() {
    unset($GLOBALS);
});
$GLOBALS = $undef;
 [2020-02-04 14:02 UTC] nikic@php.net
-Status: Verified +Status: Analyzed
 [2020-02-04 14:02 UTC] nikic@php.net
Root cause here is pretty similar to bug #78598, but a slightly different situation.

We fetch $GLOBALS in FETCH_W, and then emit undef var notice in ASSIGN op2 fetch, which invalidates our reference to $GLOBALS. This is probably going to be even trickier to fix...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 08:01:28 2024 UTC