php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64280 __destruct loop segfaults
Submitted: 2013-02-22 17:44 UTC Modified: 2013-02-24 10:18 UTC
Votes:2
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: bobwei9 at hotmail dot com Assigned:
Status: Open Package: Reproducible crash
PHP Version: master-Git-2013-02-22 (Git) OS: Mac OS X Mountain Lion
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2013-02-22 17:44 UTC] bobwei9 at hotmail dot com
Description:
------------
A destruct loop segfaults due "KERN_PROTECTION_FAILURE".

Please add some sort of counter (until 1000 for example) to every destructor to avoid segmentation faults.

____
It is not funny when someone thinks he has to produce endless core dumps...

Test script:
---------------
<?php
class getDestructed {
        public function __destruct() {
                new self;
        }
}
$class = new getDestructed;


Expected result:
----------------
Fatal error:  Allowed memory size of %ul bytes exhausted at Zend/zend_execute.h:%s (tried to allocate %i bytes) in xxx on line 3

or some restriction by a counter

Actual result:
--------------
#1  0x0000000100823ce7 in zend_call_function (fci=0x7fff5f400578, fci_cache=0x7fff5f400500, tsrm_ls=0x1016110c0) at zend_execute_API.c:941
#2  0x000000010086ab02 in zend_call_method (object_pp=0x7fff5f4006e8, obj_ce=0x1015e22a0, fn_proxy=0x7fff5f4006f8, function_name=0x100e47510 "__destruct", function_name_len=10, retval_ptr_ptr=0x0, param_count=0, arg1=0x0, arg2=0x0, tsrm_ls=0x1016110c0) at zend_interfaces.c:97
#3  0x00000001008804f8 in zend_objects_destroy_object (object=0x1027f5be0, handle=2483, tsrm_ls=0x1016110c0) at zend_objects.c:123
#4  0x000000010088e60b in zend_objects_store_del_ref_by_handle_ex (handle=2483, handlers=0x100ef1188, tsrm_ls=0x1016110c0) at zend_objects_API.c:207
#5  0x000000010088e374 in zend_objects_store_del_ref (zobject=0x1027f5b60, tsrm_ls=0x1016110c0) at zend_objects_API.c:173
#6  0x0000000100839c66 in _zval_dtor_func (zvalue=0x1027f5b60, __zend_filename=0x100e49301 "Zend/zend_execute.h", __zend_lineno=81) at zend_variables.c:54
#7  0x00000001008f4e7a in i_zval_ptr_dtor [inlined] () at /private/var/root/php-patch/Zend/zend_execute.h:35
#8  0x00000001008f4e7a in ZEND_NEW_SPEC_HANDLER (execute_data=0x1027402f0, tsrm_ls=0x1016110c0) at zend_variables.h:760
#9  0x000000010089147f in execute_ex (execute_data=0x1027402f0, tsrm_ls=0x1016110c0) at zend_vm_execute.h:356
#10 0x0000000100892390 in zend_execute (op_array=0x1015e3790, tsrm_ls=0x1016110c0) at zend_vm_execute.h:381
[...an infinite time of the same error message...]

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-02-23 10:10 UTC] laruence@php.net
-Status: Open +Status: Feedback
 [2013-02-23 10:10 UTC] laruence@php.net
you can refer to xdebug.max_nesting_level 

anyway, implement such protection needs a lots of work,  yes we can simple add a 
count to zend_call_function,  but there are many implicit function call, like 
autoloading, toString etc.

and for op_array execution, it is executed via zend_execute which is not this 
"function call"

so if we add such counter to zend_call_function, many confused question will be 
come.
 [2013-02-23 12:00 UTC] bobwei9 at hotmail dot com
-Status: Feedback +Status: Open
 [2013-02-23 12:00 UTC] bobwei9 at hotmail dot com
I'd consider creating a int implicit_function_call_count to the EG and incrementing it in zend_call_function (in zend_execute_API.h) (before the next call to f.ex. zend_execute) and then decrement? And check then there for a limit and abort it necessary with an E_ERROR? Should not be loads of code?

xdebug? Does everything have to be external to the core?
 [2013-02-24 04:49 UTC] laruence@php.net
I doubt whether this is necessary, it's a narrow wrong usage after all.
 [2013-02-24 10:18 UTC] bobwei9 at hotmail dot com
Exactly. But it is a) hard to find out what's going wrong (like a function produces an error which is also called accidentally in the error handler. How to find out the error without analyzing the globals of the core dump?) and b) more user friendly for debugging as you cannot suppose an user knows how to use gdb. I don't see any disadvantages here...
 [2017-11-27 06:51 UTC] valentiny510 at gmail dot com
Related to this... the same happens when you call self::__construct inside __construct. Test code:

class V {
   function __construct( ) {
      self::__construct( );
   }
}
new V;
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Oct 17 00:01:27 2019 UTC