php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48228 Possible memory corruption when PHP compiled using GCC 4.3.x
Submitted: 2009-05-10 22:47 UTC Modified: 2009-05-27 21:14 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: iddekingej at lycos dot com Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5.*, 6CVS (2009-05-27) OS: Linux 64bit gcc
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: iddekingej at lycos dot com
New email:
PHP Version: OS:

 

 [2009-05-10 22:47 UTC] iddekingej at lycos dot com
Description:
------------
The included example code was made for finding the reason php5.3RC2/apache2 crashed with some php website (the websie is not publicly available). The script didn't crash apache but failed differently.
The script should fail with a 'undefined variable', it does but it also displays the message "Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 140498868988960 bytes) in Unknown on line 0". (The large number is probably a memory location).

This error only happens in the following situation:
* as a web page (CLI works OK)
* restart apache
* Load the page and the memory exhausted message is displayed.
* Reload the page and no "memory exhausted" message

Software/machine:
* 64Bit amd
* Kubuntu  8.10
* Apache 2.2.9
* PHP(5.3RC2) compiled with : 
'./configure' '--enable-zip' '--enable-soap' '--enable-sockets' '--with-gd' '--with-pgsql' '--with-apxs2=/usr/bin/apxs2' '--with-gettext' '--enable-cli' '--enable-mbstring'





Reproduce code:
---------------
<?
function ex_handler($p_exception)
{
        ?> Error:<i><?=$p_exception->getMessage()?></i><br/><br/><?
}

function er_handler($p_errorno,$p_errstr,$p_errfile,$p_errline,$p_context)
{ 
   $l_exception=new Exception("Error $p_errorno at $p_errline in '$p_errfile':$p_errstr");     
   throw $l_exception;
}

  set_Exception_Handler("ex_handler");
  set_Error_Handler("er_handler",E_STRICT|E_WARNING|E_ALL|E_ERROR|E_NOTICE);
  class aa 
  {
    function check($p_a,$p_b,$p_c)
    {
      echo $p_a;
    }

    function dosome($p_b,$p_d,$p_e,$p_f,$p_g,$p_h)
    {
       return  $this->check(3,3,array("xx"=>$p_b,"xzx"=>$p_d,"xx"=>$p_e,"yy"=>$p_c));
    }
 }
  $l_aa=new aa();
  $l_aa->dosome('2',"33333333333333333","4","5",'sddddddddddddddddddddddd','ddddddddddddddddddd');
?>

Expected result:
----------------
* Undefined variable 


Actual result:
--------------
* Undefined variable 
* "Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 140498868988960 bytes) in Unknown on line 0". 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-11 20:37 UTC] iddekingej at lycos dot com
Thanks, but the latest snapshot din't fix the problem.

I managed to debug apache and php and found the following:

The field alloc_globals->mm_heap->reserve_size is (wrongly) overwritten with some address while freeing memory.  This value contains therefore a large number.
Next, in zend_mm_shutdown the following code is executed

      if (heap->reserve_size) {
         heap->reserve = _zend_mm_alloc_int(heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
      }
This failed because reserve_size contains a very large number.

The corruption of "alloc_globals->mm_heap->reserve_size" happens in the function  _zend_mm_free_int.This function is called from "shutdown_executor" about line 327.
That is "zend_ptr_stack_destroy(&EG(arg_types_stack));"

In the function _zend_mm_free_int a local var mm_block is loaded with "mm_block = ZEND_MM_HEADER_OF(p);"
This header contains size=0,next=0 (hmm size=0 sounds wrong). 
The value in "alloc_globals->mm_heap->reserve_size" is corrupted later on at the line "*cache = (zend_mm_free_block*)mm_block;" (about line 1968). 
So I guess that "cache" contains a wrong pointer.



This is as far as I could debug php.
 [2009-05-21 00:46 UTC] jani@php.net
What MPM are you using in Apache? (and when you give feedback, change 
the status to 'Open'..)
 [2009-05-21 07:41 UTC] iddekingej at lycos dot com
It is the default apache2 for kubuntu 8.10: apache2 2.2.9/Prefork
 [2009-05-21 11:03 UTC] lbarnaud@php.net
Verified with gcc 4.3.3 with -O2 on 5.2 and 5.3. (./configure --disable-all)

Shorter reproduce script:

<?

function do_throw() {
	throw new Exception();
}

class aa 
{
	function check()
	{
	}

	function dosome()
	{
		$this->check(do_throw());
	}
}
$l_aa=new aa();

$l_aa->dosome();
?>

The following patch against 5.3 may help to see the problem:

Index: Zend/zend_ptr_stack.h
===================================================================
RCS file: /repository/ZendEngine2/zend_ptr_stack.h,v
retrieving revision 1.22.2.2.2.1.2.3
diff -u -p -r1.22.2.2.2.1.2.3 zend_ptr_stack.h
--- Zend/zend_ptr_stack.h	31 Dec 2008 11:15:32 -0000	1.22.2.2.2.1.2.3
+++ Zend/zend_ptr_stack.h	21 May 2009 10:56:26 -0000
@@ -107,6 +107,9 @@ static inline void zend_ptr_stack_push(z
 static inline void *zend_ptr_stack_pop(zend_ptr_stack *stack)
 {
 	stack->top--;
+	if (stack->top < 0) {
+		return *(void**)0;
+	}
 	return *(--stack->top_element);
 }


The following patch avoids the crash (don't know exactly why):

Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.90
diff -u -p -r1.59.2.29.2.48.2.90 zend_vm_def.h
--- Zend/zend_vm_def.h	8 Apr 2009 13:19:34 -0000	1.59.2.29.2.48.2.90
+++ Zend/zend_vm_def.h	21 May 2009 11:01:28 -0000
@@ -4296,7 +4296,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTI
 			zval_ptr_dtor(&EX(object));
 		}
 		EX(called_scope) = DECODE_CTOR(EX(called_scope));
-		zend_ptr_stack_2_pop(&EG(arg_types_stack), (void**)&EX(object), (void**)&EX(fbc));
+		EX(object) = zend_ptr_stack_pop(&EG(arg_types_stack));
+		EX(fbc) = zend_ptr_stack_pop(&EG(arg_types_stack));
 	}
 
 	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
 [2009-05-21 21:17 UTC] iddekingej at lycos dot com
I have some more information about this bug:

THis bug happens in the following situation:

$l_a->someMethod(other_fy())

When in "other_fy()" a exception is raised this bug occurs.

This bug doesn't happen when calling a normal function 

e.g.
someMethod(other_fy())


This bug happens in apache as module and in the CLI. (only in the cli there is no visible clue that something did go wrong).


In the function ZEND_HANDLE_EXCEPTION_SPEC_HANDLER (zend_vm_execute.h). 
I placed some debug output (EX(fbc)->common.function_name and EG(arg_types_stack).top)
before:

while (EX(fbc)) {
      EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
      if (EX(object)) {

and after

            zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
            }
         }
         zval_ptr_dtor(&EX(object));
      }

After the exception is raised this function is called. 
The first time it is called, the variable fbc=NULL and arg_types_stack.top =3. Because 
EX(fbc)=NULL the while loop is skipped.

When this function is called the second time and fbc is not null(Contains data from the method "check") , 
and arg_type_stack.top is still 3. After the while loop arg_type_stack.top=-3, which is afcourse wrong . Because of this 
some memory corruption occurs.

So  maybe when calling a method and a expception is raised when the parameters are calculated the variable "fbc" is not set correctly 
or there is a missing "zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));"
 [2009-05-27 19:24 UTC] jani@php.net
See also bug #48408
 [2009-05-27 21:14 UTC] iddekingej at lycos dot com
I can confirm that this bug is probably caused by a compiler bug as mentioned in bug #48408.

When I compiled PHp with 4.1 and run the test script I didn't see the 
"(tried to allocate 140498868988960 bytes)" message.

I also added the debug output as described at [21 May 9:17pm UTC] and the "arg_type_stack.top=-3" bug didn't happen.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 24 00:01:27 2024 UTC