php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38090 segfault on error/exit/die-ing when stream wrapper registered
Submitted: 2006-07-13 09:09 UTC Modified: 2006-07-13 10:15 UTC
From: albert at friendly dot net Assigned:
Status: Not a bug Package: Reproducible crash
PHP Version: 5.1.4 OS: linux 2.6.16.16 on x86 (15/2)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: albert at friendly dot net
New email:
PHP Version: OS:

 

 [2006-07-13 09:09 UTC] albert at friendly dot net
Description:
------------
Registered a stream wrapper class and using it's dir_* functions (opendir/readdir). PHP segfaults when error occurs or exit/die-ing on purpose.
I'm using the CLI SAPI version of PHP 5.4.1 (vanilla).

As an added bonus I discovered something weird going on
with at least the break and continue statements. Possibly others (all?) as well. See code.

It's no dupe of #32742 (this crash happens on 5.1.4 and that bug should have been fixed in 5.0.4)
Doesn't look the same as #29358, then again, not enough info there.
Not sure if it's a dupe of #36320/#36838 ?


Reproduce code:
---------------
as per request, a cropped version of the actual source.
The complete source can be found at:
http://www.friendly.net/phpcrash/streamwrapper_dir.php.txt

function iterate()
{
  if (!($dirHandle = opendir(WRAPPERPROTOCOL.'://*')))
    return(FALSE);
  while (($fileName = readdir($dirHandle))) {
    echo "fileName=$fileName\n";
/* !!!!!!!!!
   exit-ing or die-ing here causes a segfault
   go ahead, uncomment it: */
//die;

/* btw: preceeding break/continue with cruft doesn't seem to throw off
   the parser. It even seems to skip these two 'statements'
   Is this a feature ? */
sdjkfksdfjbreak;
blablawhateverpreceedscontinueseemstobeokaycontinue;
echo 'see, skipped m n all ';
  }
  closedir($dirHandle);
}


Expected result:
----------------
Not crashing on error/exit/die

Actual result:
--------------
#0  0x0827b4d0 in zend_object_store_get_object (zobject=0x0, tsrm_ls=0x0)
    at /usr/src/php-5.1.4/Zend/zend_objects_API.c:215
        handle = 3
#1  0x08254908 in zend_call_function (fci=0xbfff87d0, fci_cache=0x0,
    tsrm_ls=0x840c060)
    at /usr/src/php-5.1.4/Zend/zend_execute_API.c:661
        tmp_object_ptr = (zval **) 0x0
        tmp_real_function_name = (zval **) 0x0
        i = 0
        original_return_value = (zval **) 0x0
        calling_symbol_table = (HashTable *) 0x0
        original_function_state_ptr = (zend_function_state *) 0x0
        original_op_array = (zend_op_array *) 0x0
        original_opline_ptr = (zend_op **) 0x854a3e0
        current_scope = (zend_class_entry *) 0x0
        calling_scope = (zend_class_entry *) 0x0
        check_scope_or_static = (zend_class_entry *) 0x0
        current_this = (zval *) 0x82657e5
        execute_data = {opline = 0x0, function_state = {
    function_symbol_table = 0x0, function = 0x0, reserved = {0x0, 0x0, 0x0,
      0x0}}, fbc = 0x0, op_array = 0x0, object = 0x0, Ts = 0x0, CVs = 0x0,
  original_in_execution = 0 '\0', symbol_table = 0x0, prev_execute_data = 0x0,
  old_error_reporting = 0x0}
        method_name = (zval *) 0x0
        params_array = (zval *) 0x0
        call_via_handler = 0
        fname = 0x0
        fname_len = 0
#2  0x08254ba5 in call_user_function_ex (function_table=0x0, object_pp=0x0,
    function_name=0x0, retval_ptr_ptr=0x0, param_count=0, params=0x0,
    no_separation=0, symbol_table=0x0, tsrm_ls=0x0)
    at /usr/src/php-5.1.4/Zend/zend_execute_API.c:579
        fci = {size = 36, function_table = 0x0, function_name = 0xbfff8850,
  symbol_table = 0x0, retval_ptr_ptr = 0xbfff884c, param_count = 0,
  params = 0x0, object_pp = 0x854a3e0, no_separation = 0 '\0'}
#3  0x08236b3e in php_userstreamop_closedir (stream=0x0, close_handle=1,
    tsrm_ls=0x0) at /usr/src/php-5.1.4/main/streams/userspace.c:1266
        func_name = {value = {lval = 137733903,
    dval = 2.5531999081323198e-313, str = {val = 0x835a70f "dir_closedir",
      len = 12}, ht = 0x835a70f, obj = {handle = 137733903, handlers = 0xc}},
  refcount = 0, type = 6 '\006', is_ref = 0 '\0'}
        retval = (zval *) 0x0
        us = (php_userstream_data_t *) 0x854a3dc
#4  0x0822fca9 in _php_stream_free (stream=0x854d33c, close_options=11,
    tsrm_ls=0x840c060)
    at /usr/src/php-5.1.4/main/streams/streams.c:342
        ret = 1
        preserve_handle = 0
        release_cast = 1
#5  0x08230314 in stream_resource_regular_dtor (rsrc=0x0, tsrm_ls=0x84859d8)
    at /usr/src/php-5.1.4/main/streams/streams.c:1373
        stream = (php_stream *) 0x854d33c
#6  0x0826bce8 in list_entry_destructor (ptr=0x854d164)
    at /usr/src/php-5.1.4/Zend/zend_list.c:184
        ld = (zend_rsrc_list_dtors_entry *) 0x841ab50
        tsrm_ls = (void ***) 0x840c060
#7  0x0826aa78 in zend_hash_apply_deleter (ht=0x8410da8, p=0x854ce2c)
    at /usr/src/php-5.1.4/Zend/zend_hash.c:576
        retval = (Bucket *) 0xbfff94fc
#8  0x0826aae7 in zend_hash_graceful_reverse_destroy (ht=0x8410da8)
    at /usr/src/php-5.1.4/Zend/zend_hash.c:642
        p = (Bucket *) 0x3
#9  0x082606cd in zend_deactivate (tsrm_ls=0x840c060)
    at /usr/src/php-5.1.4/Zend/zend.c:860
        orig_bailout = {{__jmpbuf = {0, 0, 0, 0, 0, 0}, __mask_was_saved = 0,
    __saved_mask = {__val = {0 <repeats 32 times>}}}}
        orig_bailout_set = 0 '\0'
#10 0x0821b673 in php_request_shutdown (dummy=0x0)
    at /usr/src/php-5.1.4/main/main.c:1287
        orig_bailout = {{__jmpbuf = {0, 0, 0, 0, 0, 0},
    __mask_was_saved = 67108864, __saved_mask = {__val = {3081346676,
        3221196808, 3221196316, 3221196472, 3081324584, 27, 3221196316,
        3221196524, 3081336736, 67108864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        3085188145, 0, 3085189636, 0, 3085968256, 3085967324, 72, 120,
        139734104, 120, 139733080, 3085967232}}}}
        orig_bailout_set = 0 '\0'
        report_memleaks = 1 '\001'
        tsrm_ls = (void ***) 0x840c060
#11 0x08315605 in main (argc=2, argv=0xbfff94f4)
    at /usr/src/php-5.1.4/sapi/cli/php_cli.c:1245
        pce = (zend_class_entry *) 0x0
        arg = (zval *) 0x0
        ref = (zval *) 0x0
        execute_data = {opline = 0xbfff9488, function_state = {
    function_symbol_table = 0xb7ff40fd, function = 0x8048034, reserved = {0x8,
      0xbfff92a8, 0x2e000000, 0x3}}, fbc = 0xbfff932e, op_array = 0xffffe400,
  object = 0xffffffff, Ts = 0x0, CVs = 0x0, original_in_execution = 8 '\b',
  symbol_table = 0x8048034, prev_execute_data = 0x8082f10,
  old_error_reporting = 0x756e694c}
        len = 3221198072
        argn = (zval *) 0xb7ff51de
        input = 0xbfff94fc ""
        index = 19
        argi = (zval *) 0x0
        exit_status = 0
        c = 0
        file_handle = {type = 2 '\002', filename = 0xbfff9e51 "./crash.php",
  opened_path = 0x85437e4 "\f?T\b", handle = {fd = 139702248, fp = 0x853afe8,
    stream = {handle = 0x853afe8,
      reader = 0x8272e40 <zend_stream_stdio_reader>,
      closer = 0x8272e60 <zend_stream_stdio_closer>,
      fteller = 0x8272e80 <zend_stream_stdio_fteller>, interactive = 0}},
  free_filename = 0 '\0'}
        behavior = 1
        reflection_what = 0x0
        orig_optind = 1
        orig_optarg = 0x0
        arg_free = 0xbfff9e51 "./crash.php"
        arg_excp = (char **) 0xbfff94f8
        script_file = 0xbfff9e51 "./crash.php"
        global_vars = {head = 0x0, tail = 0x0, count = 0, size = 4, dtor = 0,
  persistent = 0 '\0', traverse_ptr = 0xb7a99e74}
        interactive = 0
        module_started = 1
        lineno = 2
        exec_direct = 0x0
        exec_run = 0x0
        exec_begin = 0x0
        exec_end = 0x0
        param_error = 0x0
        hide_argv = 0
        tsrm_ls = (void ***) 0x840c060

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-07-13 09:20 UTC] albert at friendly dot net
As hinted at in my initial report: dunno if this is a dupe of #36320. iliaa<at>php.net suggests there:
"The fix you can implement involves adding a missing
clodedir() call to your script".
Which doesn't work when exiting in non-related code or due to an parsing error or such.
Anyway, this indeed doesn't segfault:

  while (($fileName = readdir($dirHandle))) {
    echo "fileName=$fileName\n";
closedir($dirHandle);
die;
  }
 [2006-07-13 09:28 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2006-07-13 09:49 UTC] albert at friendly dot net
php5.2-200607130830 segfaults as well.
Need a bt ?
 [2006-07-13 10:15 UTC] tony2001@php.net
Yes, it's a duplicate of bug #36320.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Wed Apr 01 07:00:01 2026 UTC