php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #12227 Over writing output buffer and returning it causes segfault
Submitted: 2001-07-18 06:07 UTC Modified: 2002-05-03 23:07 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: brueckner at respublica dot de Assigned: yohgaki (profile)
Status: Closed Package: Output Control
PHP Version: 4.2.0-dev OS: Linux 2.2.16-SMP
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.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: brueckner at respublica dot de
New email:
PHP Version: OS:

 

 [2001-07-18 06:07 UTC] brueckner at respublica dot de
When using ob_start() with a script included via auto_prepend_file and then doing something like this:

ob_start("my_flush");

function my_flush($buffer)
  {
    $buffer = preg_replace("/(<!--REPLACE\\s.*?-->)/e", "parse(\"\\1\")",
        $buffer);

    return $buffer;
  }

PHP 4.0.6 SIGSEGV's with this message in the error_log:

[Wed Jul 18 11:55:08 2001]  Script:  '/home/htdocs/test.php'
---------------------------------------
output.c(235) : Block 0x0824C940 status:
Beginning:  	Overrun (magic=0x08294990, expected=0x7312F8DC)
      End:	Unknown
---------------------------------------
./zend_execute.c(334) :  Freeing 0x082A8CB4 (28131 bytes), script=/home/htdocs/test.php
zend_variables.c(117) : Actual location (location was relayed)
[Wed Jul 18 11:55:08 2001] [notice] child pid 30192 exit signal Segmentation fault (11)

If I replace the line
    $buffer = preg_replace("/(<!--REPLACE\\s.*?-->)/e", "parse(\"\\1\")",
        $buffer);
with
    $newbuffer = preg_replace("/(<!--REPLACE\\s.*?-->)/e", "parse(\"\\1\")",
        $buffer);

it works fine.

Any ideas for a fix?

Harry

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-07-18 06:13 UTC] brueckner at respublica dot de
One more comment which I forgot before:

This does NOT happen when I do not use auto_prepend_file and call my function inside the main script instead.

 [2001-12-12 04:31 UTC] yohgaki@php.net
I guess you have ob_end_clean() or ob_end_flush() in your auto prepend file. Do you?
Anyway, does this happen with 4.1.0?
 [2002-01-02 13:58 UTC] lobbin@php.net
No feedback. Closing.
 [2002-01-02 18:48 UTC] yohgaki@php.net
The same issue was submitted recently and it seems there is a problem.

To Reporter: Do not change parameter passed, but assgin to new var and return new var to prevent segfault for now. Please update PHP Version if you have tried with newer PHP.

Assigned to myslef so that I don't forget this.
 [2002-02-05 18:28 UTC] yohgaki@php.net
Easy one to fix :)


<?php
ob_start("my_flush");

function my_flush($buffer)
  {
    $buffer = preg_replace("/(<!--REPLACE\\s.*?-->)/e",
"parse(\"\\1\")",
        $buffer);

    return $buffer;
  }


?>

/home/yohgaki/public_html/bugs/12227/bug.php(9) : Warning - String is not zero-terminated (ZZZZZZZZZZZZZZ
 [2002-02-07 02:29 UTC] yohgaki@php.net
Anyone who are interested in this problem.
here is a patch for this problem. This should solve unwanted free for this specific case. Question is do we really want this?

Index: main/output.c
===================================================================
RCS file: /repository/php4/main/output.c,v
retrieving revision 1.84
diff -u -r1.84 output.c
--- main/output.c       7 Feb 2002 02:50:28 -0000       1.84
+++ main/output.c       7 Feb 2002 06:31:35 -0000
@@ -164,7 +164,7 @@
                ALLOC_INIT_ZVAL(orig_buffer);
                ZVAL_STRINGL(orig_buffer, OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, 0);
                orig_buffer->refcount=2;        /* don't let call_user_function() destroy our buffer */
-               orig_buffer->is_ref=1;
+               orig_buffer->is_ref=0;
 
                ALLOC_INIT_ZVAL(z_status);
                ZVAL_LONG(z_status, status);

 [2002-02-12 22:38 UTC] yohgaki@php.net
Last patch that I memtioned still have problem with simple output handler like

ob_handler($buffer) {
  $result = $buffer;
  return $result;
}

This could happen easily when user conditinally convert buffer....

To fix this segfualt completely, it seems I have to copy buffer before pass it to user defined output handler. 
 [2002-04-05 05:19 UTC] lucifer at vengeance dot et dot tudelft dot nl
the following testcase even crashes PHP4. it seems if you assign a value to the given parameter (here $s) which is larger than the original, it will crash. copying the input into a seperate variable and work with that is a workaround. still this simple buffer overflow ought to be easy to fix?

using 4.1.1 (build dec 30, 2001):

ob_start( "handler" );

function handler( $s ) {
  $s = $s."foobar foobar foobar";
  return $s;
}
 [2002-05-03 23:07 UTC] yohgaki@php.net
This bug has been fixed in CVS. You can grab a snapshot of the
CVS version at http://snaps.php.net/


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