php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64297 Segfault after allowed memory exhausted
Submitted: 2013-02-25 13:48 UTC Modified: 2016-07-14 12:09 UTC
Votes:7
Avg. Score:4.6 ± 0.7
Reproduced:7 of 7 (100.0%)
Same Version:5 (71.4%)
Same OS:7 (100.0%)
From: jille at hexon dot cx Assigned: dmitry (profile)
Status: Closed Package: Reproducible crash
PHP Version: 5.4.12 OS: Linux
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: jille at hexon dot cx
New email:
PHP Version: OS:

 

 [2013-02-25 13:48 UTC] jille at hexon dot cx
Description:
------------
PHP crashes with a segmentation fault when we allocate more memory than allowed.

This happens in 5.4.9 as well as 5.4.12. (No other versions tested.) The only 

Different SAPI's yield different behaviours:
* cli prints the OOM-error and sends it to syslog and segfaults immediately.
* cli in gdb or valgrind doesn't print it but syslogs and segfaults the same.
* apache2handler immediately sends the OOM-error to syslog but gives an error ("Cannot redeclare class Bummer") and segfaults afterwards on the next request to that child.

The class Bummer is included from our auto_prepend_file and I'm sure it isn't accidentally included twice. Funny thing is sometimes the error is about a different class (sometimes not even one that was loaded by the auto_prepend_file but just with a require()) so my guess would be some kind of memory corruption.

I can reproduce this reliably but failed to create a small reproduction script and unfortunately can't publish the source of our libraries.

Actual result:
--------------
The OOM-error:
PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 32 bytes) in /path/to/libs/bpm.lib on line 3190

GDB:
Program received signal SIGSEGV, Segmentation fault.
_zend_mm_free_int (heap=0xfb0510, p=0x403aeda8)
    at /tmp/php-5.4.12/Zend/zend_alloc.c:2071
2071		size = ZEND_MM_BLOCK_SIZE(mm_block);
(gdb) bt
#0  _zend_mm_free_int (heap=0xfb0510, p=0x403aeda8)
    at /tmp/php-5.4.12/Zend/zend_alloc.c:2071
#1  0x00000000007a3992 in destroy_op_array (op_array=0x11f1640)
    at /tmp/php-5.4.12/Zend/zend_opcode.c:356
#2  0x00000000007bb288 in zend_hash_destroy (ht=0xfb0e20)
    at /tmp/php-5.4.12/Zend/zend_hash.c:560
#3  0x00000000007ad491 in zend_shutdown () at /tmp/php-5.4.12/Zend/zend.c:822
#4  0x000000000074ec4a in php_module_shutdown ()
    at /tmp/php-5.4.12/main/main.c:2365
#5  0x0000000000433c07 in main (argc=5, argv=0x7fffffffe648)
    at /tmp/php-5.4.12/sapi/cli/php_cli.c:1379

$ valgrind ./sapi/cli/php /path/to/memcrash.php
==5742== Memcheck, a memory error detector
==5742== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5742== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5742== Command: ./sapi/cli/php /path/to/memcrash.php
==5742== 
==5742== Conditional jump or move depends on uninitialised value(s)
==5742==    at 0x4E3B4E0: inflateReset2 (in /lib/x86_64-linux-gnu/libz.so.1.2.3.4)
==5742==    by 0x4E3B5D8: inflateInit2_ (in /lib/x86_64-linux-gnu/libz.so.1.2.3.4)
==5742==    by 0x4E364F5: uncompress (in /lib/x86_64-linux-gnu/libz.so.1.2.3.4)
==5742==    by 0x71E239: mmc_unpack_value (memcache_pool.c:337)
==5742==    by 0x723CF3: mmc_server_read_value (memcache_ascii_protocol.c:189)
==5742==    by 0x720732: mmc_pool_select (memcache_pool.c:1584)
==5742==    by 0x7211A7: mmc_pool_run (memcache_pool.c:1670)
==5742==    by 0x719635: zif_memcache_get (memcache.c:1669)
==5742==    by 0x853B58: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==5742==    by 0x80E00E: execute (zend_vm_execute.h:410)
==5742==    by 0x7AEF56: zend_execute_scripts (zend.c:1315)
==5742==    by 0x74EEE2: php_execute_script (main.c:2492)
==5742== 
==5742== Invalid read of size 8
==5742==    at 0x78717D: _zend_mm_free_int (zend_alloc.c:2071)
==5742==    by 0x7A3991: destroy_op_array (zend_opcode.c:356)
==5742==    by 0x7BB287: zend_hash_destroy (zend_hash.c:560)
==5742==    by 0x7AD490: zend_shutdown (zend.c:822)
==5742==    by 0x74EC49: php_module_shutdown (main.c:2365)
==5742==    by 0x433C06: main (php_cli.c:1379)
==5742==  Address 0x500031c0 is not stack'd, malloc'd or (recently) free'd
==5742== 
==5742== 
==5742== Process terminating with default action of signal 11 (SIGSEGV)
==5742==  Access not within mapped region at address 0x500031C0
==5742==    at 0x78717D: _zend_mm_free_int (zend_alloc.c:2071)
==5742==    by 0x7A3991: destroy_op_array (zend_opcode.c:356)
==5742==    by 0x7BB287: zend_hash_destroy (zend_hash.c:560)
==5742==    by 0x7AD490: zend_shutdown (zend.c:822)
==5742==    by 0x74EC49: php_module_shutdown (main.c:2365)
==5742==    by 0x433C06: main (php_cli.c:1379)
==5742==  If you believe this happened as a result of a stack
==5742==  overflow in your program's main thread (unlikely but
==5742==  possible), you can try to increase the size of the
==5742==  main thread stack using the --main-stacksize= flag.
==5742==  The main thread stack size used in this run was 8388608.
==5742== 
==5742== HEAP SUMMARY:
==5742==     in use at exit: 7,524,625 bytes in 20,150 blocks
==5742==   total heap usage: 2,020,371 allocs, 2,000,221 frees, 1,589,606,462 bytes allocated
==5742== 
==5742== LEAK SUMMARY:
==5742==    definitely lost: 201,072 bytes in 3,591 blocks
==5742==    indirectly lost: 3,960,481 bytes in 2,926 blocks
==5742==      possibly lost: 82,068 bytes in 53 blocks
==5742==    still reachable: 3,281,004 bytes in 13,580 blocks
==5742==         suppressed: 0 bytes in 0 blocks
==5742== Rerun with --leak-check=full to see details of leaked memory
==5742== 
==5742== For counts of detected and suppressed errors, rerun with: -v
==5742== Use --track-origins=yes to see where uninitialised values come from
==5742== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 2 from 2)
Segmentation fault

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-02-25 14:56 UTC] laruence@php.net
-Status: Open +Status: Feedback
 [2013-02-25 14:56 UTC] laruence@php.net
please remove the memcache extension then test it again.
 [2013-02-25 15:51 UTC] jille at hexon dot cx
Removing the memcache extension doesn't help. (gdb output seems the same, do you want the new valgrind output? (Takes a while))
 [2013-02-25 15:51 UTC] jille at hexon dot cx
-Status: Feedback +Status: Open
 [2013-03-01 03:12 UTC] laruence@php.net
do you get the new valgrind log?

thanks
 [2013-03-01 03:12 UTC] laruence@php.net
-Status: Open +Status: Feedback
 [2013-03-01 08:15 UTC] jille at hexon dot cx
==30922== Memcheck, a memory error detector
==30922== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==30922== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==30922== Command: ./sapi/cli/php -d auto_prepend_file=auto_prepend_prepend.lib /data/www/htdocs/wheeler/daemons/daemon_wrapper 1023 live memcrash.php
==30922== 
==30922== Invalid read of size 8
==30922==    at 0x77954D: _zend_mm_free_int (zend_alloc.c:2071)
==30922==    by 0x795D61: destroy_op_array (zend_opcode.c:356)
==30922==    by 0x7AD657: zend_hash_destroy (zend_hash.c:560)
==30922==    by 0x79F860: zend_shutdown (zend.c:822)
==30922==    by 0x741019: php_module_shutdown (main.c:2365)
==30922==    by 0x433BE6: main (php_cli.c:1379)
==30922==  Address 0x4ca5d948 is not stack'd, malloc'd or (recently) free'd
==30922== 
==30922== 
==30922== Process terminating with default action of signal 11 (SIGSEGV)
==30922==  Access not within mapped region at address 0x4CA5D948
==30922==    at 0x77954D: _zend_mm_free_int (zend_alloc.c:2071)
==30922==    by 0x795D61: destroy_op_array (zend_opcode.c:356)
==30922==    by 0x7AD657: zend_hash_destroy (zend_hash.c:560)
==30922==    by 0x79F860: zend_shutdown (zend.c:822)
==30922==    by 0x741019: php_module_shutdown (main.c:2365)
==30922==    by 0x433BE6: main (php_cli.c:1379)
==30922==  If you believe this happened as a result of a stack
==30922==  overflow in your program's main thread (unlikely but
==30922==  possible), you can try to increase the size of the
==30922==  main thread stack using the --main-stacksize= flag.
==30922==  The main thread stack size used in this run was 8388608.
==30922== 
==30922== HEAP SUMMARY:
==30922==     in use at exit: 7,553,441 bytes in 20,136 blocks
==30922==   total heap usage: 2,020,750 allocs, 2,000,614 frees, 1,564,536,722 bytes allocated
==30922== 
==30922== LEAK SUMMARY:
==30922==    definitely lost: 203,536 bytes in 3,635 blocks
==30922==    indirectly lost: 4,029,186 bytes in 2,979 blocks
==30922==      possibly lost: 70,648 bytes in 43 blocks
==30922==    still reachable: 3,250,071 bytes in 13,479 blocks
==30922==         suppressed: 0 bytes in 0 blocks
==30922== Rerun with --leak-check=full to see details of leaked memory
==30922== 
==30922== For counts of detected and suppressed errors, rerun with: -v
==30922== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Segmentation fault
 [2013-03-01 08:15 UTC] jille at hexon dot cx
-Status: Feedback +Status: Open
 [2013-03-01 09:38 UTC] laruence@php.net
nothing serious, 

so the segufalt backtrace is the same as before?
 [2013-03-01 09:43 UTC] jille at hexon dot cx
Yes. Exactly the same.
 [2013-03-01 09:47 UTC] jille at hexon dot cx
(gdb) f 3
#3  0x000000000079f861 in zend_shutdown () at /tmp/php-5.4.12/Zend/zend.c:822
822		zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
(gdb) f 2
#2  0x00000000007ad658 in zend_hash_destroy (ht=0xf9fe90)
    at /tmp/php-5.4.12/Zend/zend_hash.c:560
560				ht->pDestructor(q->pData);
(gdb) print *q
$5 = {h = 13860750752776937334, nKeyLength = 14, pData = 0x11d99b0, 
  pDataPtr = 0x0, pListNext = 0x11d9ab0, pListLast = 0x11d6fe0, pNext = 0x0, 
  pLast = 0x0, arKey = 0x7ffff7ed6f18 "udp_getsocket"}
(gdb) f 1
#1  0x0000000000795d62 in destroy_op_array (op_array=0x11d99b0)
    at /tmp/php-5.4.12/Zend/zend_opcode.c:356
356			efree(op_array->run_time_cache);
(gdb) print *op_array
$6 = {type = 2 '\002', function_name = 0x7ffff7fd4638 "udp_getSocket", 
  scope = 0x0, fn_flags = 134217728, prototype = 0x0, num_args = 0, 
  required_num_args = 0, arg_info = 0x0, refcount = 0x7ffff7fd5e20, 
  opcodes = 0x7ffff7fd7838, last = 17, vars = 0x7ffff7fd3fc8, last_var = 1, 
  T = 6, brk_cont_array = 0x0, last_brk_cont = 0, try_catch_array = 0x0, 
  last_try_catch = 0, static_variables = 0x7ffff7fd4e80, 
  this_var = 4294967295, filename = 0x7ffff7fd0ba0 "", line_start = 3, 
  line_end = 9, doc_comment = 0x0, doc_comment_len = 0, 
  early_binding = 4294967295, literals = 0x7ffff7fd4fd0, last_literal = 8, 
  run_time_cache = 0x3a0f81a0, last_cache_slot = 2, reserved = {0x0, 0x0, 0x0, 
    0x0}}
(gdb) print *op_array->run_time_cache 
Cannot access memory at address 0x3a0f81a0
 [2016-07-14 12:09 UTC] dmitry@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: dmitry
 [2016-07-14 12:09 UTC] dmitry@php.net
Memory overflow handling in php 5 wasn't graceful, and might lead to undefined behavior during request shutdown.
This is fixed in PHP-7.0
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Apr 02 09:01:31 2025 UTC