php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68606 stack overflow/segfault in zend_objects_free_object_storage
Submitted: 2014-12-15 07:18 UTC Modified: 2016-07-14 10:57 UTC
Votes:10
Avg. Score:4.5 ± 0.8
Reproduced:9 of 9 (100.0%)
Same Version:1 (11.1%)
Same OS:5 (55.6%)
From: cmshelto at gmail dot com Assigned: dmitry (profile)
Status: Assigned Package: Reproducible crash
PHP Version: 5.6.3 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2014-12-15 07:18 UTC] cmshelto at gmail dot com
Description:
------------
The garbage collector segfaults when freeing a deeply nested group of objects. The way this bug initially appeared, it was not 100000 chained objects but much less; however, they were bigger objects (more properties).

I have tested this in PHP 5.6.3 and 5.5.13 on Ubuntu 14.04 and PHP 5.5.17 on RHEL7.

The reason I think it is a stack overflow is because when I run it under valgrind with --main-stacksize=83886080 (10x the default on my machine) then I get the expected output.

As I was trying to create a short enough test case, the offending function seemed to vary but the functions 'zend_objects_store_del_ref', 'zend_objects_store_del_ref_by_handle_ex', 'zend_object_std_dtor', 'zend_hash_destroy', '_zval_ptr_dtor_wrapper', '_zval_ptr_dtor', 'i_zval_ptr_dtor', and '_zval_dtor' always seemed to be involved.

I can provide a gdb backtrace if necessary; to me, it does not appear any more interesting than the valgrind output (it is 124544 frames of the functions listed above).

Test script:
---------------
<?php
function fun()
{
    $root = NULL;

    for ($i = 0; $i < 100000; $i += 1)
    {
        $tmp = new \stdClass;
        $tmp -> aProperty = $root;
        $root = $tmp;
    }

    echo "Finished making objects!\n";
}

fun();
echo "Done!\n";
?>

Expected result:
----------------
Finished making objects!
Done!

Actual result:
--------------
Finished making objects!
Segmentation fault (core dumped)

(Valgrind output):
==6903== Memcheck, a memory error detector
==6903== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6903== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==6903== Command: ./sapi/cli/php /tmp/gc_bug.php
==6903== Parent PID: 8032
==6903== 
==6903== Stack overflow in thread 1: can't grow stack to 0xffe801ff8
==6903== 
==6903== Process terminating with default action of signal 11 (SIGSEGV)
==6903==  Access not within mapped region at address 0xFFE801FF8
==6903==    at 0x9C0101: zval_delref_p (zend.h:410)
==6903==    by 0x9C0294: i_zval_ptr_dtor (zend_execute.h:76)
==6903==    by 0x9C1564: _zval_ptr_dtor (zend_execute_API.c:427)
==6903==    by 0x9D4F1D: _zval_ptr_dtor_wrapper (zend_variables.c:188)
==6903==    by 0x9EA5FB: zend_hash_destroy (zend_hash.c:548)
==6903==    by 0xA0DBD9: zend_object_std_dtor (zend_objects.c:44)
==6903==    by 0xA0E0C8: zend_objects_free_object_storage (zend_objects.c:137)
==6903==    by 0xA151C9: zend_objects_store_del_ref_by_handle_ex (zend_objects_API.c:226)
==6903==    by 0xA14ECE: zend_objects_store_del_ref (zend_objects_API.c:178)
==6903==    by 0x9D4B0C: _zval_dtor_func (zend_variables.c:57)
==6903==    by 0x9C023A: _zval_dtor (zend_variables.h:35)
==6903==    by 0x9C0301: i_zval_ptr_dtor (zend_execute.h:79)
==6903==    by 0x9C1564: _zval_ptr_dtor (zend_execute_API.c:427)
==6903==    by 0x9D4F1D: _zval_ptr_dtor_wrapper (zend_variables.c:188)
==6903==    by 0x9EA5FB: zend_hash_destroy (zend_hash.c:548)
==6903==    by 0xA0DBD9: zend_object_std_dtor (zend_objects.c:44)
==6903==    by 0xA0E0C8: zend_objects_free_object_storage (zend_objects.c:137)
==6903==    by 0xA151C9: zend_objects_store_del_ref_by_handle_ex (zend_objects_API.c:226)
==6903==    by 0xA14ECE: zend_objects_store_del_ref (zend_objects_API.c:178)
==6903==    by 0x9D4B0C: _zval_dtor_func (zend_variables.c:57)
==6903==    by 0x9C023A: _zval_dtor (zend_variables.h:35)
==6903==    by 0x9C0301: i_zval_ptr_dtor (zend_execute.h:79)
==6903==    by 0x9C1564: _zval_ptr_dtor (zend_execute_API.c:427)
==6903==    by 0x9D4F1D: _zval_ptr_dtor_wrapper (zend_variables.c:188)
==6903==    by 0x9EA5FB: zend_hash_destroy (zend_hash.c:548)
==6903==    by 0xA0DBD9: zend_object_std_dtor (zend_objects.c:44)
==6903==    by 0xA0E0C8: zend_objects_free_object_storage (zend_objects.c:137)
==6903==    by 0xA151C9: zend_objects_store_del_ref_by_handle_ex (zend_objects_API.c:226)
==6903==    by 0xA14ECE: zend_objects_store_del_ref (zend_objects_API.c:178)
==6903==    by 0x9D4B0C: _zval_dtor_func (zend_variables.c:57)
==6903==  If you believe this happened as a result of a stack
==6903==  overflow in your program's main thread (unlikely but
==6903==  possible), you can try to increase the size of the
==6903==  main thread stack using the --main-stacksize= flag.
==6903==  The main thread stack size used in this run was 8388608.
==6903== Stack overflow in thread 1: can't grow stack to 0xffe801ff8
==6903== 
==6903== Process terminating with default action of signal 11 (SIGSEGV)
==6903==  Access not within mapped region at address 0xFFE801FF8
==6903==    at 0x4A256B0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==6903==  If you believe this happened as a result of a stack
==6903==  overflow in your program's main thread (unlikely but
==6903==  possible), you can try to increase the size of the
==6903==  main thread stack using the --main-stacksize= flag.
==6903==  The main thread stack size used in this run was 8388608.
==6903== 
==6903== HEAP SUMMARY:
==6903==     in use at exit: 39,189,162 bytes in 520,804 blocks
==6903==   total heap usage: 524,822 allocs, 4,018 frees, 47,723,472 bytes allocated
==6903== 
==6903== LEAK SUMMARY:
==6903==    definitely lost: 0 bytes in 0 blocks
==6903==    indirectly lost: 0 bytes in 0 blocks
==6903==      possibly lost: 0 bytes in 0 blocks
==6903==    still reachable: 39,189,162 bytes in 520,804 blocks
==6903==         suppressed: 0 bytes in 0 blocks
==6903== Rerun with --leak-check=full to see details of leaked memory
==6903== 
==6903== For counts of detected and suppressed errors, rerun with: -v
==6903== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-14 10:57 UTC] dmitry@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: dmitry
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC