Bug #80246 [Ana]: SEGV in zend_fetch_dimension_address_read()
| From: | nikic@php.net | Date: | Mon, 19 Oct 2020 12:53:20 +0000 |
| Subject: | Bug #80246 [Ana]: SEGV in zend_fetch_dimension_address_read() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-229747@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80246&edit=1
ID: 80246
Updated by: nikic@php.net
Reported by: sanjeev dot das at ibm dot com
Summary: SEGV in zend_fetch_dimension_address_read()
Status: Analyzed
Type: Bug
Package: CGI/CLI related
Operating System: 18.04.4 LTS
PHP Version: 7.4.11
Block user comment: N
Private report: N
New Comment:
Yes, this is a known issue with many different variations (we probably have a couple dozen bug
reports for this lying around, it's commonly found by fuzzers). My long term plan is to address
this by delaying error reporting to the end of the opcode, but I haven't gotten around to
trying that yet.
Previous Comments:
------------------------------------------------------------------------
[2020-10-19 12:41:20] cmb@php.net
Confirmed. Simpler reproducer for PHP 7:
<?php
set_error_handler(function() use(&$my_var) {
$my_var = 0;
});
$my_var = 'nual';
$my_var["foo"];
?>
and for PHP 8:
<?php
set_error_handler(function() use(&$my_var) {
$my_var = 0;
});
$my_var = 'nual';
$my_var["1a"];
?>
The problem is that we make sure that the zval IS_STRING[1], but
than trigger an error, the error handler changes the type of the
zval, but we're treating the zval still as string[2].
[1] <https://github.com/php/php-src/blob/php-7.4.11/Zend/zend_execute.c#L2386>
[2] <https://github.com/php/php-src/blob/php-7.4.11/Zend/zend_execute.c#L2426>
------------------------------------------------------------------------
[2020-10-16 15:28:11] sanjeev dot das at ibm dot com
Description:
------------
Segmentation fault is triggered due to null pointer dereference in
zend_fetch_dimension_address_read() with the given php script.
Address sanitizer shows:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==4575==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x0000016c426a bp
0x7fff1318b790 sp 0x7fff1318af60 T0)
==4575==The signal is caused by a READ memory access.
==4575==Hint: address points to the zero page.
#0 0x16c4269 in zend_fetch_dimension_address_read php-7.2.34/Zend/zend_execute.c:1800:7
#1 0x16c4269 in zend_fetch_dimension_address_read_R_slow php-7.2.34/Zend/zend_execute.c:1855
#2 0x1379a9b in ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER php-7.2.34/Zend/zend_vm_execute.h:36219:4
#3 0x11f2aad in execute_ex php-7.2.34/Zend/zend_vm_execute.h:59767:7
#4 0x11f3e92 in zend_execute php-7.2.34/Zend/zend_vm_execute.h:63804:2
#5 0xfd7e9b in zend_execute_scripts php-7.2.34/Zend/zend.c:1498:4
#6 0xd4a23a in php_execute_script php-7.2.34/main/main.c:2599:14
#7 0x171d99f in do_cli php-7.2.34/sapi/cli/php_cli.c:1011:5
#8 0x171ab8b in main php-7.2.34/sapi/cli/php_cli.c:1403:18
#9 0x7fafaac66b96 in __libc_start_main
/build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
#10 0x432279 in _start (php-7.2.34/sapi/cli/php+0x432279)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV php-7.2.34/Zend/zend_execute.c:1800:7 in
zend_fetch_dimension_address_read
==4575==ABORTING
Test script:
---------------
<?php
$my_var = null;
set_error_handler(function() use(&$my_var) {
$my_var = 0;
});
$my_var[] .= "xyz";
var_dump($my_var);
$my_var = null;
$my_var[0][0][0] .= "xyz";
var_dump($my_var);
$my_var = nual;
$my_var["foo"] . "xyz";
var_dump($my_var);
$my_Var = null;
$my_var["foo"]["bar"]["baz"] .= "xyz";
var_dump($my_var);
?>
Expected result:
----------------
No seg fault.
Actual result:
--------------
Segmentation fault.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80246&edit=1