php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65674 reaching max_execution_time might corrupt zend memory heap
Submitted: 2013-09-14 21:11 UTC Modified: 2018-01-13 11:32 UTC
Votes:8
Avg. Score:4.0 ± 1.3
Reproduced:7 of 8 (87.5%)
Same Version:3 (42.9%)
Same OS:4 (57.1%)
From: lazy404 at gmail dot com Assigned: nikic (profile)
Status: Closed Package: *General Issues
PHP Version: 5.5.3 OS: Linux
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: lazy404 at gmail dot com
New email:
PHP Version: OS:

 

 [2013-09-14 21:11 UTC] lazy404 at gmail dot com
Description:
------------
Reaching max_execution_time might corrupt zend memory heap.

Php uses setitimer(ITIMER_PROF) to limit the cpu time used by scripts.
When time is exceeded php is sent a signal. Signal handler calls zend_error() to
display "Maximum execution time of %d second%s exceeded" message.

Unfortunetly php_error_cb() uses spprintf() which allocates memory from php
memory heap, This is not safe because php heap might be in an inconsistent state.

php_eror_cb() also uses free(), which is protected by a lock so this,
can produce a deadlock, if the signal arrived during a free.

Segfault happens more than 1 in 20 runs. Example backtrace follows
#0  0x00007ffb0e0e9757 in kill () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00000000007958e6 in zend_mm_panic (message=0xbdd6cd "zend_mm_heap 
corrupted") at /usr/src/php-5.5.3/Zend/zend_alloc.c:92
#2  0x0000000000798bf3 in _zend_mm_alloc_int (heap=0x24f0300, size=79, 
__zend_filename=0xbce3d8 "/usr/src/php-5.5.3/main/spprintf.c", __zend_lineno=236,
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /usr/src/php-
5.5.3/Zend/zend_alloc.c:2018
#3  0x00000000007992fa in _zend_mm_realloc_int (heap=0x24f0300, p=0x0, size=79, 
__zend_filename=0xbce3d8 "/usr/src/php-5.5.3/main/spprintf.c",
    __zend_lineno=236, __zend_orig_filename=0x0, __zend_orig_lineno=0) at 
/usr/src/php-5.5.3/Zend/zend_alloc.c:2134
#4  0x000000000079a4bc in _erealloc (ptr=0x0, size=79, allow_failure=0, 
__zend_filename=0xbce3d8 "/usr/src/php-5.5.3/main/spprintf.c", __zend_lineno=236,
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /usr/src/php-
5.5.3/Zend/zend_alloc.c:2450
#5  0x00000000007429ba in xbuf_format_converter (xbuf=0x7fffb5b48d00, fmt=0xbcd7dd 
"PHP %s:  %s in %s on line %d", ap=0x7fffb5b48d50)
    at /usr/src/php-5.5.3/main/spprintf.c:236
#6  0x0000000000744bde in vspprintf (pbuf=0x7fffb5b48ea0, max_len=0, 
format=0xbcd7dd "PHP %s:  %s in %s on line %d", ap=0x7fffb5b48d50)
    at /usr/src/php-5.5.3/main/spprintf.c:799
#7  0x0000000000744cc9 in spprintf (pbuf=0x7fffb5b48ea0, max_len=0, 
format=0xbcd7dd "PHP %s:  %s in %s on line %d") at /usr/src/php-
5.5.3/main/spprintf.c:818
#8  0x000000000073c878 in php_error_cb (type=1, error_filename=0x7ffb0f1c0610 
"/usr/src/php-5.5.3/t.php", error_lineno=7,
    format=0xbe05f0 "Maximum execution time of %d second%s exceeded", 
args=0x7fffb5b49000) at /usr/src/php-5.5.3/main/main.c:1068
#9  0x00000000007d1cec in zend_error (type=1, format=0xbe05f0 "Maximum execution 
time of %d second%s exceeded") at /usr/src/php-5.5.3/Zend/zend.c:1110
#10 0x00000000007c070c in zend_timeout (dummy=27) at /usr/src/php-
5.5.3/Zend/zend_execute_API.c:1331
#11 <signal handler called>
#12 0x0000000000796208 in zend_mm_remove_from_free_list (heap=0x24f0300, 
mm_block=0x7ffb0d305150) at /usr/src/php-5.5.3/Zend/zend_alloc.c:849
#13 0x0000000000799171 in _zend_mm_free_int (heap=0x24f0300, p=0x7ffb0d3052e0, 
__zend_filename=0xbe2d78 "/usr/src/php-5.5.3/Zend/zend_hash.c",
    __zend_lineno=565, __zend_orig_filename=0x0, __zend_orig_lineno=0) at 
/usr/src/php-5.5.3/Zend/zend_alloc.c:2110
#14 0x000000000079a43f in _efree (ptr=0x7ffb0d3052e0, __zend_filename=0xbe2d78 
"/usr/src/php-5.5.3/Zend/zend_hash.c", __zend_lineno=565,

I have also observed deadlocks coused by free's lock on production servers running
php as fastcgi.



Test script:
---------------
<?php
ini_set("max_execution_time", 1);


for($a= 0; $a < 100000; $a++) {

$ta=array();

for ($i = 0; $i < 10000; $i++)
{
        array_push($ta,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i);
}

}


echo "ok";


Expected result:
----------------
Status: 500 Internal Server Error
X-Powered-By: PHP/5.5.3
Content-type: text/html

PHP Fatal error:  Maximum execution time of 1 second exceeded in /usr/src/php-
5.5.3/t.php on line 11
/usr/src/php-5.5.3/t.php(11) : Fatal error - Maximum execution time of 1 second 
exceeded


Actual result:
--------------
Status: 500 Internal Server Error
X-Powered-By: PHP/5.5.3
Content-type: text/html

zend_mm_heap corrupted
Naruszenie ochrony pamięci (core dumped)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-06 23:09 UTC] b8kich at gmail dot com
working fine in 5.5.13 for me
 [2014-12-03 23:30 UTC] lazy404 at gmail dot com
How many times did You try ?

I still see deadlocks and segfaults with 5.6.3
 [2018-01-13 11:32 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2018-01-13 11:32 UTC] nikic@php.net
This has been fixed in PHP 7.1. PHP will no longer interrupt internal function calls on timeout.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 28 02:01:28 2024 UTC