php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51552 debug_backtrace() causes segmentation fault and/or memory issues
Submitted: 2010-04-13 19:02 UTC Modified: 2010-06-11 11:04 UTC
Votes:4
Avg. Score:3.8 ± 0.8
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:3 (75.0%)
From: kkotowicz at gmail dot com Assigned: dmitry
Status: Closed Package: Reproducible crash
PHP Version: 5.3.2 OS: win/linux
Private report: No CVE-ID:
 [2010-04-13 19:02 UTC] kkotowicz at gmail dot com
Description:
------------
Under certain conditions, when result from debug_backtrace() function is modified, segmentation fault is triggered. 

I noticed this error on PHP 5.2.6/Win and PHP 5.3.2/Linux x64.

PHP 5.3.2 configure line:

'./configure' '--with-apxs2=/usr/local/apache22/bin/apxs' '--prefix=/usr/local/php53' '--with-zlib=/usr/' '--with-openssl=no' '--with-mysql=no' '--with-mssql=/usr/local/freetds' '--with-pgsql=/usr/local/pg83' '--with-gd' '--without-sqlite' '--with-pdo-pgsql=/usr/local/pg83' '--disable-tokenizer' '--without-pdo-sqlite' '--disable-xmlreader' '--disable-xmlwriter' '--with-jpeg-dir=/usr' '--disable-filter' '--enable-soap' '--enable-mbstring' '--with-libdir=lib64' '--enable-gd-native-ttf' '--with-freetype-dir=/usr' '--with-oci8=instantclient,/usr/local/lib/oracle11.7'

The error is hard to trigger, I narrowed it down to below test case. Points to note:
 - array_walk with 3 parameters must be used 
 - array_walk must iterate over array with at least 2 elements
 - walking function creates an object that uses debug_backtrace() and unsets itself from top of the trace (PEAR_Error object does that).
 - the error has something to do with references, because when walk() uses 3rd parameter by-reference, error disappears.


Test script:
---------------
<?php

class i_use_backtrace { 
  function __construct() {
    $this->backtrace = debug_backtrace();
    unset($this->backtrace[0]['object']); // PEAR_Error uses the same behaviour!
  }
}

// function walk(&$element, $key, &$params) would behave correctly
function walk(&$element, $key, $params) {
  $r = new i_use_backtrace; // you could also use new PEAR_Error
}

$a = array(0, 0);
array_walk($a, 'walk' , array(0));

Expected result:
----------------
No output

Actual result:
--------------
Segmentation fault



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-04-15 00:27 UTC] kkotowicz at gmail dot com
The problem also exists in 

PHP 5.2.10-2ubuntu6.4 with Suhosin-Patch 0.9.7 (cli)
 [2010-04-23 19:13 UTC] felipe@php.net
It doesn't crash for me, but the Valgrind points actually memory issues (invalid write/read, and so on):

[...]
==25121== ERROR SUMMARY: 16 errors from 16 contexts (suppressed: 90 from 3)
==25121== malloc/free: in use at exit: 3,673 bytes in 76 blocks.
==25121== malloc/free: 30,671 allocs, 30,595 frees, 3,020,064 bytes allocated.
==25121== For counts of detected errors, rerun with: -v
==25121== searching for pointers to 76 not-freed blocks.
==25121== checked 1,007,216 bytes.
==25121==
 [2010-04-28 17:42 UTC] kkotowicz at gmail dot com
I tried compiling PHP 5.3.2 and noticed that when compiling with --enable-debug the error disappears (no segmentation fault). Exact configure line is:

# ./configure  --disable-xml --disable-libxml --disable-simplexml --disable-xmlreader --disable-xmlwriter --disable-dom --without-pear --enable-debug 

Standard compilation without debugging symbols:

# ./configure  --disable-xml --disable-libxml --disable-simplexml --disable-xmlreader --disable-xmlwriter --disable-dom --without-pear 

and the error (I lack gdb skills so I don't know what to report more)

root@xxx:/home/xxx/debugPHP/php-5.3.2/sapi/cli# gdb --args ./php bug.php
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) run
Starting program: /home/xxx/debugPHP/php-5.3.2/sapi/cli/php bug.php
[Thread debugging using libthread_db enabled]
[New Thread 0xb7d116b0 (LWP 1627)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7d116b0 (LWP 1627)]
zend_hash_num_elements (ht=0x868f630) at /home/xxx/debugPHP/php-5.3.2/Zend/zend_hash.c:1014
1014    {
 [2010-04-28 18:30 UTC] kkotowicz at gmail dot com
gdb backtrace for the failing script below:

#0  zend_hash_num_elements (ht=0x868f630) at /home/xxx/debugPHP/php-5.3.2/Zend/zend_hash.c:1014
#1  0x082b6665 in debug_backtrace_get_args (curpos=<value optimized out>)
    at /home/xxx/debugPHP/php-5.3.2/Zend/zend_variables.h:45
#2  0x082b68a2 in zend_fetch_debug_backtrace (return_value=0x868f854, skip_last=1, provide_object=1)
    at /home/xxx/debugPHP/php-5.3.2/Zend/zend_builtin_functions.c:2195
#3  0x082b6b44 in zif_debug_backtrace (ht=0, return_value=0x868f854, return_value_ptr=0x0, this_ptr=0x0,
    return_value_used=1) at /home/xxx/debugPHP/php-5.3.2/Zend/zend_builtin_functions.c:2269
#4  0x082ec629 in zend_do_fcall_common_helper_SPEC (execute_data=0x86bffa4)
    at /home/xxx/debugPHP/php-5.3.2/Zend/zend_vm_execute.h:313
#5  0x082c6540 in execute (op_array=0x869036c) at /home/xxx/debugPHP/php-5.3.2/Zend/zend_vm_execute.h:104
#6  0x0829a77a in zend_call_function (fci=0x85c9348, fci_cache=0x85c936c)
    at /home/xxx/debugPHP/php-5.3.2/Zend/zend_execute_API.c:947
#7  0x081efdd8 in php_array_walk (target_hash=0x868d824, userdata=0xbfc3d704, recursive=0)
    at /home/xxx/debugPHP/php-5.3.2/ext/standard/array.c:1109
#8  0x081f035f in zif_array_walk (ht=3, return_value=0x868de00, return_value_ptr=0x0, this_ptr=0x0,
    return_value_used=0) at /home/xxx/debugPHP/php-5.3.2/ext/standard/array.c:1151
#9  0x082ec629 in zend_do_fcall_common_helper_SPEC (execute_data=0x86bfe10)
    at /home/xxx/debugPHP/php-5.3.2/Zend/zend_vm_execute.h:313
#10 0x082c6540 in execute (op_array=0x868d78c) at /home/xxx/debugPHP/php-5.3.2/Zend/zend_vm_execute.h:104
#11 0x082a4cd4 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /home/xxx/debugPHP/php-5.3.2/Zend/zend.c:1194
#12 0x08252928 in php_execute_script (primary_file=0xbfc3fb88) at /home/xxx/debugPHP/php-5.3.2/main/main.c:2260
#13 0x08324976 in main (argc=2, argv=0xbfc3fce4) at /home/xxx/debugPHP/php-5.3.2/sapi/cli/php_cli.c:1192
 [2010-04-28 19:40 UTC] kkotowicz at gmail dot com
The same problem occurs when running php 5.3.2/Win32

Backtrace generated from MS Debug Diagnostic Tool below:

Entry point   php!mainCRTStartup 
Create time   2010-04-28 19:34:00 
Time spent in user mode   0 Days 0:0:0.15 
Time spent in kernel mode   0 Days 0:0:0.0 

Function     Arg 1     Arg 2     Arg 3   Source 
php5!zend_hash_num_elements+4     00000000     00000000     1007dbc0    
php5!_zval_copy_ctor_func+61     01170378     011a0080     01170a50    
php5!zend_startup_builtin_functions+2b54     00000000     01171648     011a0278    
php5!zend_fetch_debug_backtrace+21a     01170830     00c0ea4c     00000001    
php5!zend_fetch_debug_backtrace+374     00000000     01170830     00000000    
php5!execute+cdf     011a0278     01172d68     011a0278    
php5!execute+4c25     00000000     10549738     10544688    
php5!execute+1f0     0129cb18     0116f5f0     00c0eb30    
php5!zend_call_function+6c1     10544688     105446ac     00c0eb70    
php5!zif_max+3d3     0116f5f0     00c0eb30     00000000    
php5!zif_array_walk+cf     00000003     01170260     00000000    
php5!execute+cdf     011a0080     0116f668     011a0080    
php5!execute+4c25     00c0ec28     00c0fed4     00c0fcbc    
php5!execute+1f0     0116f668     00c0fed4     00000000    
php5!zend_execute_scripts+be     00000008     00000000     00000003    
php5!php_execute_script+1e2     00c0fed4     0040642c     00000001    
php!main+a9a     00000004     003d31d0     003d3450    
php!memcpy+160     0000000e     00000000     7ffdf000    
kernel32!BaseProcessStart+23     00402dda     00000000     00000000    




PHP5!ZEND_HASH_NUM_ELEMENTS+4In php__PID__2516__Date__04_28_2010__Time_07_34_10PM__865__Second_Chance_Exception_C0000005.dmp the assembly instruction at php5!zend_hash_num_elements+4 in E:\tmp\php_bug\bin\php5.dll from The PHP Group has caused an access violation exception (0xC0000005) when trying to read from memory location 0x00000008 on thread 0
 [2010-04-29 18:44 UTC] kkotowicz at gmail dot com
-Summary: Modifying debug_backtrace() output causes segmentation fault +Summary: debug_backtrace() causes segmentation fault and/or memory issues
 [2010-04-29 18:44 UTC] kkotowicz at gmail dot com
I dug depper into the issue, it looks as debug_backtrace() and functions accepting references are causing the problem. 

Here's the script that describes it:

<?php
function walk($element, $key, $p) {
    var_dump(func_get_args());
    $backtrace = debug_backtrace();
    //var_dump($backtrace);
    unset($backtrace); // commenting this line crashes PHP 
}

$a = range(1,10);

array_walk($a, 'walk', 'testthis');
?>

this results in:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(0)
  [2]=>
  string(8) "testthis"
}
array(3) {
  [0]=>
  int(2)
  [1]=>
  int(1)
  [2]=>
  string(8) "!   1   "
}
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(2)
}
array(3) {
  [0]=>
  int(4)
  [1]=>
  int(3)
  [2]=>
  string(4) "!   "
}

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate
 134217728 bytes) in E:\tmp\php_bug\bug.php on line 4

for the first iteration, everything is ok. But each next time walk() is called, the $p argument gets some random value, thus pointing to the memory issues with debug_backtrace(). The backtrace itself will show some garbage each next time.
 [2010-06-08 14:14 UTC] tony2001@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: dmitry
 [2010-06-11 10:53 UTC] dmitry@php.net
Automatic comment from SVN on behalf of dmitry
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=300371
Log: Fixed bug #51552 (debug_backtrace() causes segmentation fault and/or memory issues)
 [2010-06-11 11:04 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2010-06-11 11:04 UTC] dmitry@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 16:02:22 2014 UTC