php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51431 Problem with method_exists and autoloader
Submitted: 2010-03-29 21:07 UTC Modified: 2010-05-17 11:11 UTC
From: mboland at internl dot net Assigned: ilia (profile)
Status: Wont fix Package: Reproducible crash
PHP Version: 5.2SVN-2010-03-29 (snap) OS: Linux
Private report: No CVE-ID: None
 [2010-03-29 21:07 UTC] mboland at internl dot net
Description:
------------
A call to method_exists may invoke a class loader. If the class loader is complicated enough, PHP will reallocate the stack to make more room. Once the class loader returns, PHP will then dereference a variable that is no longer valid.


Test script:
---------------
<?php
    function recurse($i) {
        if ($i > 0) {
            recurse($i - 1);
        } else {
            class C { }
        }
    }
    function autoload_function($unused) {
        recurse(17);
    }
    spl_autoload_register('autoload_function');
    method_exists('C', 'foo');


Actual result:
--------------
$ gdb --args ./sapi/cli/php crash.php
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 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".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/mboland/src/php5.2-201003291630/sapi/cli/php...done.
(gdb) break zif_method_exists 
Breakpoint 1 at 0x832a702: file /home/mboland/src/php5.2-201003291630/Zend/zend_builtin_functions.c, line 898.
(gdb) r
Starting program: /home/mboland/src/php5.2-201003291630/sapi/cli/php crash.php
[Thread debugging using libthread_db enabled]

Breakpoint 1, zif_method_exists (ht=2, return_value=0x854e124, 
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_builtin_functions.c:898
898             if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &klass, &method_name)==FAILURE) {
(gdb) n
901             if (Z_TYPE_PP(klass) == IS_OBJECT) {
(gdb) print method_name 
$1 = (zval **) 0x854344c
(gdb) print *method_name
$2 = (zval *) 0x854b6e4
(gdb) print *method_name
$3 = {value = {lval = 139780340, dval = 6.435048036853826e-314, str = {
      val = 0x854e0f4 "foo", len = 3}, ht = 0x854e0f4, obj = {
      handle = 139780340, handlers = 0x3}}, refcount = 1, type = 6 '\006', 
  is_ref = 0 '\000'}
(gdb) watch *method_name 
Hardware watchpoint 2: *method_name
(gdb) c
Continuing.
Hardware watchpoint 2: *method_name

Old value = (zval *) 0x854b6e4
New value = (zval *) 0x5a5a5a5a
memset () at ../sysdeps/i386/i686/memset.S:85
85      ../sysdeps/i386/i686/memset.S: No such file or directory.
        in ../sysdeps/i386/i686/memset.S
Current language:  auto
The current source language is "auto; currently asm".
(gdb) bt
#0  memset () at ../sysdeps/i386/i686/memset.S:85
#1  0x082fc11c in _zend_mm_free_int (heap=0x848a1d8, p=0x8543444, 
    __zend_filename=0x845db80 "/home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h", __zend_lineno=73, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_alloc.c:1952
#2  0x082fcdd0 in _zend_mm_realloc_int (heap=0x848a1d8, p=0x8543444, size=520, 
    __zend_filename=0x845db80 "/home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h", __zend_lineno=73, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_alloc.c:2237
#3  0x082fd040 in _erealloc (ptr=0x8543444, size=520, allow_failure=0, 
    __zend_filename=0x845db80 "/home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h", __zend_lineno=73, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_alloc.c:2321
#4  0x0833ca69 in zend_ptr_stack_2_push (stack=0x8489580, a=0x1, b=0x0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h:73


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-03-29 21:11 UTC] mboland at internl dot net
Forgot to mention: the test script crashes with a segmentation fault.
The PHP used was built with
./configure --enable-debug
 [2010-03-29 21:12 UTC] mboland at internl dot net
Bugs that are caused by a problem similar to this:-
#50360
#46753
 [2010-03-31 10:46 UTC] kalle@php.net
Does this also happens on 5.3SVN?
 [2010-03-31 12:56 UTC] mboland at internl dot net
PHP 5.3 uses ZEND_VM_STACK_GROW_IF_NEEDED instead of ZEND_PTR_STACK_RESIZE_IF_NEEDED to grow the argument stack, so no.
 [2010-05-12 16:35 UTC] mike@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: ilia
 [2010-05-12 16:35 UTC] mike@php.net
So I suppose this becomes a "Won't fix" unless Ilia thinks otherwise for 5.2
 [2010-05-17 11:11 UTC] iliaa@php.net
-Status: Assigned +Status: Wont fix
 [2010-05-17 11:11 UTC] iliaa@php.net
Non-issue in 5.3, requires too big of a chance in 5.2 to address.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 14:01:28 2024 UTC