php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47522 __toString() segfault (PHP_5_2 only)
Submitted: 2009-02-27 18:52 UTC Modified: 2011-01-06 03:14 UTC
Votes:15
Avg. Score:4.6 ± 0.7
Reproduced:13 of 13 (100.0%)
Same Version:6 (46.2%)
Same OS:6 (46.2%)
From: ms419 at freezone dot co dot uk Assigned:
Status: Wont fix Package: Reproducible crash
PHP Version: 5.2CVS-2009-02-27 (snap) OS: Debian
Private report: No CVE-ID: None
 [2009-02-27 18:52 UTC] ms419 at freezone dot co dot uk
Description:
------------
http://cgi.sfu.ca/~jdbates/tmp/php/200902270/core

I am experiencing a reproducible segfault. I experience it with PHP 5.2.4 and 5.2.6.

The segfault occurs at this expression: strlen($repository) where $repository is an object with a __toString() method.

By substituting this expression, the segfault does not occur: strlen($repository->__toString())

To try to debug this segfault, I compiled a recent 5.2 snapshot with --enable-debug. It produced the above linked core file, which I opened with gdb to print a backtrace: http://cgi.sfu.ca/~jdbates/tmp/php/200902270/screenlog

I am not sure what should be my next steps to help fix this segfault?


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-27 19:28 UTC] felipe@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2009-03-02 19:23 UTC] ms419 at freezone dot co dot uk
Unfortunately I have been unable to reproduce this segfault in a short script - it seems whenever I try to cut something out of the larger project where it occurs, the segfault disappears.

Casting the object to a string in a parent function does not produce a segfault, while calling a function and casting in the called function does. Even passing the object as the first as opposed to fourth argument of the function causes the segfault to disappear.

The segfault occurs at line eight of this file: http://code.google.com/p/qubit-toolkit/source/browse/trunk/qubit/apps/qubit/modules/repository/templates/showIsdiahSuccess.php#8

Since r2041, a workaround has been committed to the render_title() function: http://code.google.com/p/qubit-toolkit/source/detail?r=2041

Removing that workaround causes the segfault to reappear.

I am eager to help any way I can - but I have had no luck reproducing this segfault in a short script...
 [2009-03-20 15:04 UTC] josh dot butts at vertive dot com
We have also tracked down a segfault which appears to be directly related to this.  

<?=html_entity_decode($form->getElement('query'))?>

where $form is a Zend_Form object from Zend Framework.  Not able to reproduce it out of context but within the  context of the site happens almost 100% of the time.  Removing html_entity_decode() fixes the segfault, as does casting (string) on the $form, or calling $form->render().  The implicit call to __toString() appears to be the root cause of this problem.
 [2009-03-20 15:37 UTC] pajoye@php.net
Please provide a small script to reproduce the problem. The Zend Framework is not a small script. You can also post a bug there and ask them to figure out what's wrong.
 [2009-03-28 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-07-30 22:12 UTC] alex at innovacomputing dot com
I'm able to reproduce this as well on PHP 5.2.9 on Debian Linux 5.0 i386, but not on amd64 versions.

I was able to reproduce this by unpacking Zend Framework 1.8.4 and running the following PHP script:

<?php
require_once 'Zend/Date.php';
$x = new Zend_Date();
$y = new Zend_Date($x);

In this case, it seems to happen when passing an object to strpos().  I've noticed that when you do this, it does not immediately segfault.  Instead, it continues executing PHP code, until the Zend_Date constructor returns, at which point it segfaults.

I've posted a workaround for Zend Framework at http://framework.zend.com/issues/browse/ZF-7413 .

Here's a backtrace from gdb:
#0  0x0824d2a0 in zif_strpos (ht=2, return_value=0xb6900238, return_value_ptr=0x0, this_ptr=0x0,
    return_value_used=1) at /usr/src/php5/source/php5-5.2.9/ext/standard/string.c:1814
#1  0x0832a413 in zend_do_fcall_common_helper_SPEC (execute_data=0xbf822cec)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:200
#2  0x08315580 in execute (op_array=0xb688ea80)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:92
#3  0x08329cd6 in zend_do_fcall_common_helper_SPEC (execute_data=0xbf82311c)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:234
#4  0x08315580 in execute (op_array=0xb688a90c)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:92
#5  0x08329cd6 in zend_do_fcall_common_helper_SPEC (execute_data=0xbf823a5c)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:234
#6  0x08315580 in execute (op_array=0x9c163d4)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:92
#7  0x08329cd6 in zend_do_fcall_common_helper_SPEC (execute_data=0xbf823c7c)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:234
#8  0x08315580 in execute (op_array=0x9c0dbbc)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_vm_execute.h:92
#9  0x082e28ce in zend_eval_string (
    str=0xbf82593e "require_once \"Zend/Date.php\"; $x = new Zend_Date(); $y = new Zend_Date($x);", retval_ptr=0x0, string_name=0x8551cfc "Command line code")
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_execute_API.c:1217
#10 0x082e2a3b in zend_eval_string_ex (
    str=0xbf82593e "require_once \"Zend/Date.php\"; $x = new Zend_Date(); $y = new Zend_Date($x);", retval_ptr=0x0, string_name=0x8551cfc "Command line code", handle_exceptions=1)
    at /usr/src/php5/source/php5-5.2.9/Zend/zend_execute_API.c:1251
#11 0x083755f9 in main (argc=3, argv=0xbf824044)
    at /usr/src/php5/source/php5-5.2.9/sapi/cli/php_cli.c:1178
 [2009-07-31 20:45 UTC] stas@php.net
Verified for 5.2.x, not reproduceable for 5.3.x

Analysis: 
the problem is cause by applying strpos() to Zend_Date object. When convert_to_string in strpos() is called to convert object to string, Zend_Date::__toString is called and on the course of the execution the variable stack is reallocated. However haystack variable still points to the old stack location, which means any access to it will produce the UMR. Valgrind dump:

=22070== Invalid read of size 4
==22070==    at 0x81E36FB: zif_strpos (string.c:1814)
==22070==    by 0x8292509: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:200)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8251FC7: zend_eval_string (zend_execute_API.c:1214)
==22070==    by 0x825211E: zend_eval_string_ex (zend_execute_API.c:1248)
==22070==    by 0x82CAACF: main (in /root/php)
==22070==  Address 0x4C876E4 is 52 bytes inside a block of size 256 free'd
==22070==    at 0x40054FB: realloc (vg_replace_malloc.c:306)
==22070==    by 0x8291F2C: zend_do_fcall_common_helper_SPEC (zend_ptr_stack.h:73)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==22070==    by 0x827F6AF: execute (zend_vm_execute.h:92)
==22070==    by 0x8291E75: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)

Not sure how to fix it.
 [2011-01-06 03:14 UTC] aharvey@php.net
-Status: Verified +Status: Wont fix
 [2011-01-06 03:14 UTC] aharvey@php.net
5.2 is now end of lifed. Closing, since this doesn't occur on 5.3.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 19:01:29 2024 UTC