php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79784 Use after free if changing array during undef var during array write fetch
Submitted: 2020-07-04 04:35 UTC Modified: 2020-07-07 12:21 UTC
From: changochen1 at gmail dot com Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 8.0Git-2020-07-04 (Git) OS:
Private report: No CVE-ID: None
 [2020-07-04 04:35 UTC] changochen1 at gmail dot com
Description:
------------
LOG:
---
php: /home/yongheng/php_clean/Zend/zend_hash.c:71: void _zend_is_inconsistent(const HashTable *, const char *, int): Assertion `0' failed.
---

Test script:
---------------
<?
try {
    define ( ob_start ( function () {
        global $a ;
        array ( list ( $a   ) = $b  ) ;
    }
    , 20 )  )  ;
}catch ( Error ) {
    $a [ $c ] = 'x' ;
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-07 10:39 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2020-07-07 10:39 UTC] nikic@php.net
Reduced:

<?php
ob_start(function () { 
    $GLOBALS['a'] = null;
}, 20);
$a[$c] = 'x' ;

Valgrind:

==1075083== Invalid read of size 4
==1075083==    at 0x9D66FF: _zend_is_inconsistent (zend_hash.c:54)
==1075083==    by 0x9DDEFD: zend_hash_find (zend_hash.c:2240)
==1075083==    by 0x9ED077: zend_hash_find_ex (zend_hash.h:188)
==1075083==    by 0x9F3911: zend_fetch_dimension_address_inner (zend_execute.c:2085)
==1075083==    by 0x9F3B53: zend_fetch_dimension_address_inner_W (zend_execute.c:2152)
==1075083==    by 0xA617C5: ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER (zend_vm_execute.h:47136)
==1075083==    by 0xA69F6F: execute_ex (zend_vm_execute.h:55946)
==1075083==    by 0xA6A21D: zend_execute (zend_vm_execute.h:56094)
==1075083==    by 0x9C442A: zend_execute_scripts (zend.c:1667)
==1075083==    by 0x92BF71: php_execute_script (main.c:2537)
==1075083==    by 0xAA91B6: do_cli (php_cli.c:955)
==1075083==    by 0xAAA2AE: main (php_cli.c:1353)
==1075083==  Address 0x8ebebb8 is 8 bytes inside a block of size 56 free'd
==1075083==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1075083==    by 0x98A6FA: _efree_custom (zend_alloc.c:2426)
==1075083==    by 0x98A851: _efree (zend_alloc.c:2546)
==1075083==    by 0x9DBCF8: zend_array_destroy (zend_hash.c:1662)
==1075083==    by 0x9BFF72: rc_dtor_func (zend_variables.c:57)
==1075083==    by 0x9EE297: zend_assign_to_variable (zend_execute.h:141)
==1075083==    by 0xA2DBE3: ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER (zend_vm_execute.h:22094)
==1075083==    by 0xA67C3F: execute_ex (zend_vm_execute.h:54181)
==1075083==    by 0x9ACB1D: zend_call_function (zend_execute_API.c:785)
==1075083==    by 0x9D25DD: zend_fcall_info_call (zend_API.c:3496)
==1075083==    by 0x945A43: php_output_handler_op (output.c:960)
==1075083==    by 0x945E03: php_output_op (output.c:1057)
==1075083==  Block was alloc'd at
==1075083==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1075083==    by 0x98B83F: __zend_malloc (zend_alloc.c:2992)
==1075083==    by 0x98A689: _malloc_custom (zend_alloc.c:2417)
==1075083==    by 0x98A7D3: _emalloc (zend_alloc.c:2536)
==1075083==    by 0x9D718E: _zend_new_array (zend_hash.c:278)
==1075083==    by 0xA61A3E: ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER (zend_vm_execute.h:47182)
==1075083==    by 0xA69F6F: execute_ex (zend_vm_execute.h:55946)
==1075083==    by 0xA6A21D: zend_execute (zend_vm_execute.h:56094)
==1075083==    by 0x9C442A: zend_execute_scripts (zend.c:1667)
==1075083==    by 0x92BF71: php_execute_script (main.c:2537)
==1075083==    by 0xAA91B6: do_cli (php_cli.c:955)
==1075083==    by 0xAAA2AE: main (php_cli.c:1353)
 [2020-07-07 11:07 UTC] nikic@php.net
A bit more obvious test case:

<?php
set_error_handler(function () { 
    $GLOBALS['a'] = null;
});
$a[$c] = 'x' ;

This is quite similar to bug #78598, with the difference that the relevant notice here comes from an undef var, rather than undef offset.
 [2020-07-07 12:21 UTC] nikic@php.net
-Summary: Assertion fail in _zend_is_inconsistent +Summary: Use after free if changing array during undef var during array write fetch
 [2020-07-07 12:25 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=62bec0e083aee4cba17d459fb4e07e1599772b12
Log: Fixed bug #79784
 [2020-07-07 12:25 UTC] nikic@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Sep 29 14:01:25 2020 UTC