Bug #69295 [Ver->Csd]: segfault w/ memory corruption in _efree() on unserialize
| From: | nikic@php.net | Date: | Sun, 01 Jan 2017 13:48:24 +0000 |
| Subject: | Bug #69295 [Ver->Csd]: segfault w/ memory corruption in _efree() on unserialize | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-206284@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=69295&edit=1
ID: 69295
Updated by: nikic@php.net
Reported by: brian dot carpenter at gmail dot com
Summary: segfault w/ memory corruption in _efree() on
unserialize
-Status: Verified
+Status: Closed
Type: Bug
Package: Reproducible crash
Operating System: Debian 7
PHP Version: PHP-7
-Assigned To:
+Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
Some time ago the USE_ZEND_ALLOC=0 fallback allocator handlers have been adjusted to check for OOM,
so this issue is resolved now.
Previous Comments:
------------------------------------------------------------------------
[2016-08-08 15:27:29] cmb@php.net
I can reproduce invalid reads/writes (apparently NULL pointer
derefs) with current PHP-5.6 and master (didn't check other
versions) with Anatol's test script (the original isn't available
anymore; I had to concatenate the strings in Anatol's script to
make it work). However, valgrind doesn't report an unrecognised
instruction (which might be bogus anyway, as it's possible that
"the instruction is legitimate but Valgrind doesn't handle it").
The following has been produced by running against a debug build
of current master (e20e9c6):
vagrant@debian-8:/vagrant/php-src$ USE_ZEND_ALLOC=0 valgrind -q sapi/cli/php -n
../69295.php
==4581== Invalid write of size 8
==4581== at 0x4C2F467: memset (vg_replace_strmem.c:1094)
==4581== by 0x63F8B1: zend_hash_real_init_ex (zend_hash.c:154)
==4581== by 0x63FB50: zend_hash_real_init (zend_hash.c:203)
==4581== by 0x59000E: php_var_unserialize_ex (var_unserializer.re:716)
==4581== by 0x58EAB1: process_nested_data (var_unserializer.re:372)
==4581== by 0x58EEA0: object_common2 (var_unserializer.re:469)
==4581== by 0x58FD4F: php_var_unserialize_ex (var_unserializer.re:875)
==4581== by 0x58EAB1: process_nested_data (var_unserializer.re:372)
==4581== by 0x58EEA0: object_common2 (var_unserializer.re:469)
==4581== by 0x58FD4F: php_var_unserialize_ex (var_unserializer.re:875)
==4581== by 0x58EAB1: process_nested_data (var_unserializer.re:372)
==4581== by 0x590051: php_var_unserialize_ex (var_unserializer.re:719)
==4581== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4581==
==4581==
==4581== Process terminating with default action of signal 11 (SIGSEGV)
==4581== Access not within mapped region at address 0x0
==4581== at 0x4C2F467: memset (vg_replace_strmem.c:1094)
==4581== by 0x63F8B1: zend_hash_real_init_ex (zend_hash.c:154)
==4581== by 0x63FB50: zend_hash_real_init (zend_hash.c:203)
==4581== by 0x59000E: php_var_unserialize_ex (var_unserializer.re:716)
==4581== by 0x58EAB1: process_nested_data (var_unserializer.re:372)
==4581== by 0x58EEA0: object_common2 (var_unserializer.re:469)
==4581== by 0x58FD4F: php_var_unserialize_ex (var_unserializer.re:875)
==4581== by 0x58EAB1: process_nested_data (var_unserializer.re:372)
==4581== by 0x58EEA0: object_common2 (var_unserializer.re:469)
==4581== by 0x58FD4F: php_var_unserialize_ex (var_unserializer.re:875)
==4581== by 0x58EAB1: process_nested_data (var_unserializer.re:372)
==4581== by 0x590051: php_var_unserialize_ex (var_unserializer.re:719)
==4581== If you believe this happened as a result of a stack
==4581== overflow in your program's main thread (unlikely but
==4581== possible), you can try to increase the size of the
==4581== main thread stack using the --main-stacksize= flag.
==4581== The main thread stack size used in this run was 8388608.
Segmentation fault
------------------------------------------------------------------------
[2015-06-08 20:09:47] stas@php.net
As these seem to be reproducible only in PHP 7, no need to list as security. Also, the second one
seems to be completely different issue, so I'd suggest filing a separate issue.
------------------------------------------------------------------------
[2015-06-08 18:37:30] brian dot carpenter at gmail dot com
I have another test case that causes a similar crash (at least according to the valgrind output).
vex amd64->IR: unhandled instruction bytes: 0xF3 0x4D 0xF 0xBC 0xE4 0x45 0x1 0xC4
==59766== valgrind: Unrecognised instruction at address 0x1319a3a.
==59766== at 0x1319A3A: zend_mm_alloc_pages (zend_alloc.c:483)
==59766== by 0x131B81C: zend_mm_alloc_small_slow (zend_alloc.c:1190)
==59766== by 0x155F573: virtual_cwd_startup (zend_virtual_cwd.c:431)
==59766== by 0x1412DCC: zend_startup (zend.c:640)
==59766== by 0x11C6F98: php_module_startup (main.c:2066)
==59766== by 0x181CFCC: php_cgi_startup (cgi_main.c:915)
==59766== by 0x43B4AC: main (cgi_main.c:1894)
==59766== Your program just tried to execute an instruction that Valgrind
==59766== did not recognise. There are two possible reasons for this.
==59766== 1. Your program has a bug and erroneously jumped to a non-code
==59766== location. If you are running Memcheck and you just saw a
==59766== warning about a bad jump, it's probably your program's fault.
==59766== 2. The instruction is legitimate but Valgrind doesn't handle it,
==59766== i.e. it's Valgrind's fault. If you think this is the case or
==59766== you are not sure, please let us know and we'll try to fix it.
==59766== Either way, Valgrind will now raise a SIGILL signal which will
==59766== probably kill your program.
==59766==
==59766== Process terminating with default action of signal 4 (SIGILL)
==59766== Illegal opcode at address 0x1319A3A
==59766== at 0x1319A3A: zend_mm_alloc_pages (zend_alloc.c:483)
==59766== by 0x131B81C: zend_mm_alloc_small_slow (zend_alloc.c:1190)
==59766== by 0x155F573: virtual_cwd_startup (zend_virtual_cwd.c:431)
==59766== by 0x1412DCC: zend_startup (zend.c:640)
==59766== by 0x11C6F98: php_module_startup (main.c:2066)
==59766== by 0x181CFCC: php_cgi_startup (cgi_main.c:915)
==59766== by 0x43B4AC: main (cgi_main.c:1894)
Illegal instruction
I can't get a stack trace in gdb, all I get is this:
Starting program: /home/geeknik/php-src/sapi/cgi/php-cgi test00-min
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
X-Powered-By: PHP/7.0.0-dev
Content-type: text/html; charset=UTF-8
<br />
<b>Fatal error</b>: Uncaught EngineException: Call to undefined function t() in
/home/geeknik/php-tmp/out/fuzzer04/crashes/test00-min:2
Stack trace:
#0 {main}
thrown in <b>/home/geeknik/php-tmp/out/fuzzer04/crashes/test00-min</b> on line
<b>2</b><br />
[Inferior 1 (process 41113) exited with code 0377]
Hexdump:
0000000 3f3c 6870 0a70 6124 613d 7272 7961 8028
0000010 612e 7272 7961 2928 3b29 2874 3b29
000001e
Test case: https://www.dropbox.com/s/zhelyjjnuw67v39/test00-min?dl=0
------------------------------------------------------------------------
[2015-05-22 09:54:39] kaplan@php.net
Let's start by fixing it for PHP 7? Then we can dig into the 5.5/5.6 reproduction.
------------------------------------------------------------------------
[2015-04-28 05:38:57] stas@php.net
I am still unable to reproduce it anywhere but PHP 7.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=69295
--
Edit this bug report at https://bugs.php.net/bug.php?id=69295&edit=1