Edit report at https://bugs.php.net/bug.php?id=61115&edit=1

 ID:                 61115
 Updated by:         cataphr...@php.net
 Reported by:        ni...@php.net
 Summary:            Stream related segfault on fatal error in
                     php_stream_context_del_link
-Status:             Open
+Status:             Analyzed
 Type:               Bug
 Package:            Reproducible crash
 PHP Version:        5.4.0RC7
 Block user comment: N
 Private report:     N

 New Comment:

I don't think this can be solved without significant changes.

The stream stores a pointer directly to the context structure (and increments 
the context resource refcount), but on an unorderly shutdown the resources are 
simply destroyed in inverse order of created. _php_stream_free then makes 
invalid reads, not just on the place that causes this segfault, but also near 
the end when it tries to decrease the context refcount.

I think the solution here would be to have the stream store the context 
resource id instead of the context structure (basically adding one level of 
indirection). We may be able to this without breaking binary compatibility, and 
the details of the stream structure are supposedly private (see comment on 
php_streams.h), but I have no doubt this would be a very problematic change 
nonetheless.


Previous Comments:
------------------------------------------------------------------------
[2012-02-16 21:59:09] ni...@php.net

Description:
------------
<?php

$arrayLarge = array_fill(0, 113663, '*');

$resourceFileTemp = fopen('php://temp', 'wr');
stream_context_set_params($resourceFileTemp, array());
preg_replace('', function () { }, $resourceFileTemp);

The above script produces a segfault. The array_fill line is irrelevant for the 
bug itself, but I needed it to get a segfault on non-debug builds too (without 
it it only segfaulted on debug builds.)

The type of the file resource is irrelevant, it is not restricted to php://temp.

The preg_replace + function() { } only serves the purpose to create a fatal 
error with the file argument, but apart from that should be irrelevant (it also 
occurs in lots of other situations that create a fatal error in a function 
call.)

This segfault basically occurs in situations where:
1. A file resource is opened
2. Some stream operation is performed on it
3. A fatal error is issued from a function which the file resource was passed to

Here is the backtrace:


(gdb) run workingFile5_segfault.php 
Starting program: /usr/local/bin/php workingFile5_segfault.php
[Thread debugging using libthread_db enabled]

Catchable fatal error: Object of class Closure could not be converted to string 
in /home/nikic/dev/my-fuzzer/results/workingFile5_segfault.php on line 8

Program received signal SIGSEGV, Segmentation fault.
0x084c95cb in php_stream_context_del_link (context=0xb73cbddc, 
    stream=0xb73cba00) at /home/nikic/dev/php-src/main/streams/streams.c:2256
2256            for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(context-
>links));
(gdb) bt
#0  0x084c95cb in php_stream_context_del_link (context=0xb73cbddc, 
    stream=0xb73cba00) at /home/nikic/dev/php-src/main/streams/streams.c:2256
#1  0x084c4953 in _php_stream_free (stream=0xb73cba00, close_options=3, 
    tsrm_ls=0x8b26050) at /home/nikic/dev/php-src/main/streams/streams.c:449
#2  0x084c48a4 in _php_stream_free (stream=0xb73cbb90, close_options=11, 
    tsrm_ls=0x8b26050) at /home/nikic/dev/php-src/main/streams/streams.c:406
#3  0x084c7059 in stream_resource_regular_dtor (rsrc=0xb73cbca0, 
    tsrm_ls=0x8b26050) at /home/nikic/dev/php-src/main/streams/streams.c:1578
#4  0x085587f3 in list_entry_destructor (ptr=0xb73cbca0)
    at /home/nikic/dev/php-src/Zend/zend_list.c:183
#5  0x08555fc6 in zend_hash_apply_deleter (ht=0x8b280ac, p=0xb73cbc4c)
    at /home/nikic/dev/php-src/Zend/zend_hash.c:650
#6  0x08556154 in zend_hash_graceful_reverse_destroy (ht=0x8b280ac)
    at /home/nikic/dev/php-src/Zend/zend_hash.c:687
#7  0x085589d5 in zend_destroy_rsrc_list (ht=0x8b280ac, tsrm_ls=0x8b26050)
    at /home/nikic/dev/php-src/Zend/zend_list.c:239
#8  0x0854474a in zend_deactivate (tsrm_ls=0x8b26050)
    at /home/nikic/dev/php-src/Zend/zend.c:940
#9  0x084a6b4d in php_request_shutdown (dummy=0x0)
    at /home/nikic/dev/php-src/main/main.c:1781
#10 0x086907c5 in do_cli (argc=2, argv=0xbffff3d4, tsrm_ls=0x8b26050)
    at /home/nikic/dev/php-src/sapi/cli/php_cli.c:1169
#11 0x08691058 in main (argc=2, argv=0xbffff3d4)
    at /home/nikic/dev/php-src/sapi/cli/php_cli.c:1356

I was not yet able to understand the source of the segfault; would be nice if 
someone who knows the stream stuff better could give a hand :)



------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=61115&edit=1

Reply via email to