php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57564 Segfault when copying __call()
Submitted: 2007-03-07 14:01 UTC Modified: 2007-12-27 16:16 UTC
From: sebastian@php.net Assigned:
Status: Closed Package: runkit (PECL)
PHP Version: 5_2 CVS-2007-03-07 OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: sebastian@php.net
New email:
PHP Version: OS:

 

 [2007-03-07 14:01 UTC] sebastian@php.net
Description:
------------
See below.

Reproduce code:
---------------
<?php
class Mixin
{
    public function __call($message, $arguments)
    {
    }
}

class Test
{
}

runkit_method_copy('Test', '__call', 'Mixin');

$t = new Test;
$t->test();

Expected result:
----------------
No segfault.

Actual result:
--------------
sb@wopr-mobile ~ % gdb /usr/local/php-5.2-debug/bin/php
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) r test.php
Starting program: /usr/local/php-5.2-debug/bin/php test.php
[Thread debugging using libthread_db enabled]
[New Thread -1214802240 (LWP 5576)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1214802240 (LWP 5576)]
0xbf868c7d in ?? ()
(gdb) bt
#0  0xbf868c7d in ?? ()
#1  0x083800fd in zend_call_function (fci=0xbf868bd8, fci_cache=0xbf868bfc) at /usr/local/src/php/php-5.2/Zend/zend_execute_API.c:984
#2  0x083a43a9 in zend_call_method (object_pp=0xbf868cbc, obj_ce=0x8619440, fn_proxy=0x861955c, function_name=0x84e1780 "__call", 
    function_name_len=6, retval_ptr_ptr=0xbf868c7c, param_count=2, arg1=0x8619b20, arg2=0x8617178)
    at /usr/local/src/php/php-5.2/Zend/zend_interfaces.c:88
#3  0x083adfea in zend_std_call_user_call (ht=0, return_value=0x86171b4, return_value_ptr=0x0, this_ptr=0x86171f0, return_value_used=0)
    at /usr/local/src/php/php-5.2/Zend/zend_object_handlers.c:657
#4  0x083b1ad4 in zend_do_fcall_common_helper_SPEC (execute_data=0xbf868e70) at /usr/local/src/php/php-5.2/Zend/zend_vm_execute.h:200
#5  0x083b2721 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0xbf868e70) at /usr/local/src/php/php-5.2/Zend/zend_vm_execute.h:322
#6  0x083b1624 in execute (op_array=0x861792c) at /usr/local/src/php/php-5.2/Zend/zend_vm_execute.h:92
#7  0x0838d14d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/local/src/php/php-5.2/Zend/zend.c:1134
#8  0x0833863f in php_execute_script (primary_file=0xbf86b1c8) at /usr/local/src/php/php-5.2/main/main.c:1788
#9  0x08406ae0 in main (argc=2, argv=0xbf86b334) at /usr/local/src/php/php-5.2/sapi/cli/php_cli.c:1127
(gdb) f 1
#1  0x083800fd in zend_call_function (fci=0xbf868bd8, fci_cache=0xbf868bfc) at /usr/local/src/php/php-5.2/Zend/zend_execute_API.c:984
984                     ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, EX(function_state).function->common.return_reference?fci->retval_ptr_ptr:NULL, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
(gdb) p *fci
$1 = {size = 36, function_table = 0x280, function_name = 0xbf868c0c, symbol_table = 0x0, retval_ptr_ptr = 0xbf868c7c, param_count = 2, 
  params = 0xbf868c1c, object_pp = 0xbf868cbc, no_separation = 1 '\001'}
(gdb) p *fci_cache
$2 = {initialized = 1 '\001', function_handler = 0xbf868bc4, calling_scope = 0x8619440, object_pp = 0xbf868cbc}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-12-27 15:56 UTC] pecl at stefan-marr dot de
There has been a small mistake in php_runkit_method_copy. magic methods had been registered with wrong pointer (points to the already overridden stack location instead to function in hash table) 

Patch follows:

Index: runkit_methods.c
===================================================================
RCS file: /repository/pecl/runkit/runkit_methods.c,v
retrieving revision 1.7
diff -u -r1.7 runkit_methods.c
--- runkit_methods.c	7 Jun 2006 17:35:33 -0000	1.7
+++ runkit_methods.c	27 Dec 2007 20:52:46 -0000
@@ -375,7 +375,7 @@
 								  char *sclass, int sclass_len, char *sfunc, int sfunc_len TSRMLS_DC)
 {
 	zend_class_entry *dce, *sce;
-	zend_function dfe, *sfe;
+	zend_function dfe, *sfe, *dfeInHashTable;
 
 	if (php_runkit_fetch_class_method(sclass, sclass_len, sfunc, sfunc_len, &sce, &sfe TSRMLS_CC) == FAILURE) {
 		return FAILURE;
@@ -397,12 +397,12 @@
 	dfe.common.scope = dce;
 #endif
 
-	if (zend_hash_add(&dce->function_table, dfunc, dfunc_len + 1, &dfe, sizeof(zend_function), NULL) == FAILURE) {
+	if (zend_hash_add(&dce->function_table, dfunc, dfunc_len + 1, &dfe, sizeof(zend_function), &dfeInHashTable) == FAILURE) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error adding method to class %s::%s()", dclass, dfunc);
 		return FAILURE;
 	}
 
-	PHP_RUNKIT_ADD_MAGIC_METHOD(dce, dfunc, &dfe);
+	PHP_RUNKIT_ADD_MAGIC_METHOD(dce, dfunc, dfeInHashTable);
 
 	zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t)php_runkit_update_children_methods, 5, dce, dce, &dfe, dfunc, dfunc_len);
 
Index: tests/bug10300.phpt
===================================================================
RCS file: tests/bug10300.phpt
diff -N tests/bug10300.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/bug10300.phpt	27 Dec 2007 20:52:46 -0000
@@ -0,0 +1,27 @@
+--TEST--
+Bug #10300 Segfault when copying __call()
+--SKIPIF--
+<?php if(!extension_loaded("runkit") || !RUNKIT_FEATURE_MANIPULATION) print "skip"; ?>
+--INI--
+error_reporting=E_ALL
+display_errors=on
+--FILE--
+<?php
+class Mixin
+{
+    public function __call($message, $arguments)
+    {
+    }
+}
+
+class Test
+{
+}
+
+runkit_method_copy('Test', '__call', 'Mixin');
+
+$t = new Test;
+$t->test();
+?>
+--EXPECT--
+
 [2007-12-27 16:16 UTC] sb at sebastian-bergmann dot de
This bug has been fixed in CVS.

In case this was a documentation problem, the fix will show up at the
end of next Sunday (CET) on pecl.php.net.

In case this was a pecl.php.net website problem, the change will show
up on the website in short time.
 
Thank you for the report, and for helping us make PECL better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 12:01:31 2024 UTC