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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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: Thu Nov 21 13:01:29 2024 UTC