php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67237 about failure logic when erealloc returns null in zend_stack_push function
Submitted: 2014-05-09 07:11 UTC Modified: 2020-03-21 16:24 UTC
Votes:6
Avg. Score:4.2 ± 0.9
Reproduced:6 of 6 (100.0%)
Same Version:3 (50.0%)
Same OS:3 (50.0%)
From: xleesmx at naver dot com Assigned: cmb (profile)
Status: Closed Package: *General Issues
PHP Version: 5.5Git-2014-05-09 (snap) OS: CentOS 6.3
Private report: No CVE-ID: None
 [2014-05-09 07:11 UTC] xleesmx at naver dot com
Description:
------------
Hi

I am running Apache/2.4.7 with PHP-5.5.10. apache processes exits with segmentation fault. 

Below is gdb backtrace of coredump.

Core was generated by `/usr/local/apache/bin/httpd -k start'.
Program terminated with signal 11, Segmentation fault.
#0  zend_stack_push (stack=0x7f4454043a20, element=0x7f44540439f8, size=40) at /php-5.5.10/Zend/zend_stack.c:42
42              stack->elements[stack->top] = (void *) emalloc(size);
Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.23-13.el6.x86_64 glibc-2.12-1.80.el6.x86_64 keyutils-libs-1.4-4.el6.x86_64 krb5-libs-1.9-33.el6.x86_64 libcom_err-1.41.12-12.el6.x86_64 libcurl-7.19.7-26.el6_2.4.x86_64 libgcc-4.4.6-4.el6.x86_64 libidn-1.18-2.el6.x86_64 libpng-1.2.49-1.el6_2.x86_64 libselinux-2.0.94-5.3.el6.x86_64 libssh2-1.2.2-7.el6_2.3.x86_64 libxml2-2.7.6-4.el6_2.4.x86_64 nspr-4.9-1.el6.x86_64 nss-3.13.3-6.el6.x86_64 nss-softokn-3.12.9-11.el6.x86_64 nss-softokn-freebl-3.12.9-11.el6.x86_64 nss-sysinit-3.13.3-6.el6.x86_64 nss-util-3.13.3-2.el6.x86_64 openldap-2.4.23-26.el6.x86_64 openssl-1.0.1e-16.el6_5.7.x86_64 pcre-7.8-6.el6.x86_64 sqlite-3.6.20-1.el6.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) bt full
#0  zend_stack_push (stack=0x7f4454043a20, element=0x7f44540439f8, size=40) at /php-5.5.10/Zend/zend_stack.c:42
No locals.
#1  0x00007f44f85ebfc9 in compile_file (file_handle=0x7f44dc5e5bf0, type=2, tsrm_ls=0x7f44540008c0) at Zend/zend_language_scanner.l:586
        original_lex_state = {yy_leng = 0, yy_start = 0x0, yy_text = 0x0, yy_cursor = 0x0, yy_marker = 0x0, yy_limit = 0x0, yy_state = 0, state_stack = {top = 0, max = 0, elements = 0x0}, heredoc_label_stack = {top = 0, 
            max = 0, elements = 0x0, top_element = 0x0, persistent = 0 '\000'}, in = 0x0, lineno = 0, filename = 0x0, script_org = 0x0, script_org_size = 0, script_filtered = 0x0, script_filtered_size = 0, input_filter = 0, 
          output_filter = 0, script_encoding = 0x0}
        op_array = 0x7f44540057e0
        original_active_op_array = 0x0
        retval = 0x7f44540057e0
        compiler_result = <value optimized out>
        compilation_successful = 0 '\000'
        retval_znode = {op_type = 1, u = {op = {constant = 1, var = 1, num = 1, hash = 1, opline_num = 1, jmp_addr = 0x1, zv = 0x1, literal = 0x1, ptr = 0x1}, constant = {value = {lval = 1, dval = 4.9406564584124654e-324, 
                str = {val = 0x1 <Address 0x1 out of bounds>, len = 0}, ht = 0x1, obj = {handle = 1, handlers = 0x0}}, refcount__gc = 1, type = 1 '\001', is_ref__gc = 0 '\000'}, op_array = 0x1}, EA = 0}
        original_in_compilation = 0 '\000'
#2  0x00007f44f847cdb6 in phar_compile_file (file_handle=0x7f44dc5e5bf0, type=2, tsrm_ls=0x7f44540008c0) at /php-5.5.10/ext/phar/phar.c:3383
        __orig_bailout = 0x7f44dc5e5b20
        __bailout = {{__jmpbuf = {139933731674912, 6551483121047815493, 139933731675120, 139931444556144, 0, 139934210498040, 6551543673771640133, 6551482302351525189}, __mask_was_saved = 0, __saved_mask = {__val = {
                6945978732095995904, 0, 139931377940828, 139933731675184, 2, 139930034503680, 33176160, 0, 139933731675216, 0, 139931377935896, 139933731674432, 7, 139931377937672, 139931377936776, 139933994763424}}}}
        res = <value optimized out>
        name = 0x0
        failed = 0
        phar = 0x7f44dc5e59c0
#3  0x00007f44f861f087 in zend_execute_scripts (type=2, tsrm_ls=0x7f44540008c0, retval=0x0, file_count=1) at /php-5.5.10/Zend/zend.c:1308
        files = {{gp_offset = 40, fp_offset = 32580, overflow_arg_area = 0x7f44dc5e5b00, reg_save_area = 0x7f44dc5e5a90}}
        i = <value optimized out>
        file_handle = 0x7f44dc5e5bf0
        orig_op_array = 0x0
        orig_retval_ptr_ptr = 0x0
        orig_interactive = 0
#4  0x00007f44f86e0d6b in php_handler (r=0x7f4450132690) at /php-5.5.10/sapi/apache2handler/sapi_apache2.c:669
        zfd = {type = ZEND_HANDLE_MAPPED, filename = 0x7f4450133f28 "XXXX.html", 
          opened_path = 0x7f4454005990 "XXXX.html", handle = {fd = 1409309392, fp = 0x7f4454005ad0, stream = {handle = 0x7f4454005ad0, 
              isatty = 0, mmap = {len = 3068, pos = 0, map = 0x0, buf = 0x7f44c20e7000 <Address 0x7f44c20e7000 out of bounds>, old_handle = 0x0, old_closer = 0}, reader = 0x7f44f85cfa40 <_php_stream_read>, 
              fsizer = 0x7f44f85b5970 <php_zend_stream_fsizer>, closer = 0x7f44f85b5940 <php_zend_stream_mmap_closer>}}, free_filename = 0 '\000'}
        __orig_bailout = 0x0
        __bailout = {{__jmpbuf = {139931443792064, -6601578868975745723, 139931377936016, 0, 139933994763424, 3, 6551543673744377157, 6551481965238666565}, __mask_was_saved = 0, __saved_mask = {__val = {139933731675276, 
                139931377942056, 139934259366448, 1343438697, 32966328, 81, 139931377943792, 2, 139931377935896, 139931377939568, 139934236069016, 1095765325, 139934259366962, 32458856, 1, 1343440176}}}}
        ctx = 0x7f448c14a428
        conf = 0x1f1acd8
        brigade = 0x7f448c14aae8
        bucket = <value optimized out>
        rv = <value optimized out>
        parent_req = 0x7f448c154970
        tsrm_ls = 0x7f44540008c0
#5  0x0000000000449dd0 in ap_run_handler (r=0x7f4450132690) at config.c:170
        pHook = <value optimized out>
        n = <value optimized out>
        rv = -1
#6  0x000000000044df5e in ap_invoke_handler (r=0x7f4450132690) at config.c:439
        handler = <value optimized out>
        p = <value optimized out>
        result = 0
        old_handler = 0x0
        ignore = <value optimized out>
#7  0x000000000046059a in ap_process_async_request (r=0x7f4450132690) at http_request.c:317
        c = 0x7f44ec0cc4a0
        access_status = 0
#8  0x000000000045cc70 in ap_process_http_async_connection (c=0x7f44ec0cc4a0) at http_core.c:143
        r = 0x7f4450132690
        cs = 0x7f44ec0cc478
#9  ap_process_http_connection (c=0x7f44ec0cc4a0) at http_core.c:228
No locals.
#10 0x00000000004547a0 in ap_run_process_connection (c=0x7f44ec0cc4a0) at connection.c:41
        pHook = <value optimized out>
        n = <value optimized out>
        rv = -1
#11 0x0000000000469305 in process_socket (thd=0x7f44ec001fe8, dummy=<value optimized out>) at event.c:970
        c = <value optimized out>
        conn_id = 218
        rc = <value optimized out>
        sbh = 0x7f44ec0ccbc0
#12 worker_thread (thd=0x7f44ec001fe8, dummy=<value optimized out>) at event.c:1815
        ti = <value optimized out>
        process_slot = 3
        thread_slot = 26
        csd = 0x7f44ec0cc220
---Type <return> to continue, or q <return> to quit--- 
        cs = 0x7f44ec0cc428
        ptrans = 0x7f44ec0cc198
        rv = <value optimized out>
        is_idle = 0
        te = 0x0
#13 0x000000310f207851 in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
#14 0x000000310eee767d in clone () from /lib64/libc.so.6
No symbol table info available.


so, I saw zend.stack.c:42 source code.

 33 ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size)
 34 {
 35         if (stack->top >= stack->max) {         /* we need to allocate more memory */
 36                 stack->elements = (void **) erealloc(stack->elements,
 37                                    (sizeof(void **) * (stack->max += STACK_BLOCK_SIZE)));
 38                 if (!stack->elements) {
 39                         return FAILURE;
 40                 }
 41         }
 42         stack->elements[stack->top] = (void *) emalloc(size);
 43         memcpy(stack->elements[stack->top], element, size);
 44         return stack->top++;
 45 }


I think the problem is line 39. In this function fail logic when erealloc function returns null is just return FAILURE;. but in line 37, stack->max value has been already plus STACK_BLOCK_SIZE
I think that statck->max value has been wrong when erealloc function returns null consequentially. so if zend_stack_push function called again, segmentation fault occurs in line 42.

Do I exactly understand this problem? please help me this problem.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-08-07 03:26 UTC] qzerolee at gmail dot com
Hi

I am running Apache/2.4.9 with PHP 5.5.8 on SuSE 11. httpd processes exits with segfault (sig 11).

This is my backtrace of coredump:

#0  zend_stack_push (stack=0x7fc232f447e0, element=0x7fc232f447b8, size=<value optimized out>) at /home/lee/x86/code/php-5.5.8/Zend/zend_stack.c:42
#1  0x00007fc2327efae8 in compile_file (file_handle=0x7fff8bb6df10, type=2) at Zend/zend_language_scanner.l:586
#2  0x00007fc23281dfbc in zend_execute_scripts (type=2, retval=0x0, file_count=1) at /home/lee/x86/code/php-5.5.8/Zend/zend.c:1308
#3  0x00007fc2328d1d1f in php_handler (r=0x8fde88) at /home/lee/x86/code/php-5.5.8/sapi/apache2handler/sapi_apache2.c:669
#4  0x000000000044ef0a in ap_run_handler (r=0x8fde88) at config.c:170
#5  0x0000000000452e66 in ap_invoke_handler (r=0x8fde88) at config.c:439
#6  0x0000000000465200 in ap_internal_redirect (new_uri=<value optimized out>, r=<value optimized out>) at http_request.c:644
#7  0x00007fc232f4e3c5 in handler_redirect (r=0x91b270) at mod_rewrite.c:5105
#8  0x000000000044ef0a in ap_run_handler (r=0x91b270) at config.c:170
#9  0x0000000000452e66 in ap_invoke_handler (r=0x91b270) at config.c:439
#10 0x0000000000465632 in ap_process_async_request (r=0x91b270) at http_request.c:317
#11 0x000000000046578f in ap_process_request (r=0x74ff40) at http_request.c:363
#12 0x0000000000461c45 in ap_process_http_sync_connection (c=<value optimized out>) at http_core.c:190
#13 ap_process_http_connection (c=<value optimized out>) at http_core.c:231
#14 0x000000000045960a in ap_run_process_connection (c=0x8f6bc0) at connection.c:41
#15 0x000000000046be16 in child_main (child_num_arg=<value optimized out>) at prefork.c:704
#16 0x000000000046c114 in make_child (s=0x6bf538, slot=10) at prefork.c:800
#17 0x000000000046cc56 in perform_idle_server_maintenance (p=<value optimized out>) at prefork.c:902
#18 prefork_run (p=<value optimized out>) at prefork.c:1090
#19 0x0000000000435618 in ap_run_mpm (pconf=0x696138, plog=0x6c3378, s=0x6bf538) at mpm_common.c:98
#20 0x000000000042fa12 in main (argc=3, argv=0x7fff8bb6e678) at main.c:777
 [2014-09-11 12:03 UTC] thomas at partyflock dot nl
It seems the stack is not properly initialized.
It happens sporadically but often enough on my production servers.
I could not reproduce this on my test server for the same script.

Important note: I have noticed ALL segfaults happen while file_handle points to files in a subdirectory of de www root, namely in /images ...
Multiple files there exhibit the problem, but not consistently at all.

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f1965a4089d in zend_stack_push (stack=stack@entry=0x7f1966205df8 <compiler_globals+696>, element=element@entry=0x7f1966205dd0 <compiler_globals+656>, size=size@entry=40) at /tmp/buildd/php5-5.6.0+dfsg/Zend/zend_stack.c:42
42		stack->elements[stack->top] = (void *) emalloc(size);
warning: File "/tmp/buildd/php5-5.6.0+dfsg/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
	add-auto-load-safe-path /tmp/buildd/php5-5.6.0+dfsg/.gdbinit
line to your configuration file "/root/.gdbinit".
To completely disable this security protection add
	set auto-load safe-path /
line to your configuration file "/root/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
	info "(gdb)Auto-loading safe path"
(gdb) p *stack
$1 = {top = 0, max = 64, elements = 0x0}
(gdb) up
#1  0x00007f1965a09e9b in compile_file (file_handle=file_handle@entry=0x7fffcf56a230, type=2) at Zend/zend_language_scanner.l:584
584			zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
(gdb) p *file_handle
$2 = {type = ZEND_HANDLE_MAPPED, filename = 0x7f19530a1bc0 "/home/party/public_html/images/countryflag.php", opened_path = 0x7f1969e15188 "/home/party/public_html/images/countryflag.php", handle = {fd = 1776374424, fp = 0x7f1969e15298, 
    stream = {handle = 0x7f1969e15298, isatty = 0, mmap = {len = 1635, pos = 0, map = 0x0, buf = 0x7f1952f75000 <error: Cannot access memory at address 0x7f1952f75000>, old_handle = 0x0, old_closer = 0x0}, 
      reader = 0x7f19659f6950 <_php_stream_read>, fsizer = 0x7f19659dbb20 <php_zend_stream_fsizer>, closer = 0x7f19659dbb00 <php_zend_stream_mmap_closer>}}, free_filename = 0 '\000'}
 [2020-03-21 16:24 UTC] cmb@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2020-03-21 16:24 UTC] cmb@php.net
erealloc() is no longer supposed to ever return NULL (i.e. it is
infallible); therefore this ticket is obsolete.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 13:01:29 2024 UTC