php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68252 segfault in Zend/zend_hash.c in function _zend_hash_del_el
Submitted: 2014-10-17 14:07 UTC Modified: 2014-10-28 09:07 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: bugs at milos dot nz Assigned: laruence (profile)
Status: Closed Package: Reproducible crash
PHP Version: master-Git-2014-10-17 (Git) OS: Linux 3.16 (Gentoo)
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: bugs at milos dot nz
New email:
PHP Version: OS:

 

 [2014-10-17 14:07 UTC] bugs at milos dot nz
Description:
------------
WordPress sites with certain plugins enabled cause a segmentation fault. Several different sites with different plugins cause this and the segmentation fault is the same. I have not encountered the issue with any isolated PHP script so I cannot currently be more specific than this.

Commenting out most of the _zend_hash_del_el() function resolves the issue, however this must either reduce performance, cause memory leaks or other anomalies, so if anything this is a temporary workaround:

static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint32_t idx, Bucket *p)
{
    Bucket *prev = NULL;

    /*if (!(ht->u.flags & HASH_FLAG_PACKED)) {
        uint32_t nIndex = p->h & ht->nTableMask;
        uint32_t i = ht->arHash[nIndex];

        if (i != idx) {
            prev = ht->arData + i;
            while (Z_NEXT(prev->val) != idx) {
                i = Z_NEXT(prev->val);
                prev = ht->arData + i;
            }
        }
    }*/

    _zend_hash_del_el_ex(ht, idx, p, prev);
}

Test script:
---------------
I am not able to identify exactly what code causes the segmentation fault so cannot provide a test script at this current point in time, but the segmentation fault is 100% reproducible on my system.

Expected result:
----------------
No segmentation fault.

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.
_zend_hash_del_el (p=0x7fffeff117b0, idx=1725, ht=0xf81890) at /root/tmp/php-src/Zend/zend_hash.c:658
658                             while (Z_NEXT(prev->val) != idx) {
(gdb) bt
#0  _zend_hash_del_el (p=0x7fffeff117b0, idx=1725, ht=0xf81890) at /root/tmp/php-src/Zend/zend_hash.c:658
#1  zend_hash_apply_deleter (ht=ht@entry=0xf81890, idx=idx@entry=1725, p=p@entry=0x7fffeff117b0) at /root/tmp/php-src/Zend/zend_hash.c:973
#2  0x000000000074b0a9 in zend_hash_reverse_apply (ht=0xf81890, apply_func=apply_func@entry=0x729ee0 <clean_non_persistent_function>) at /root/tmp/php-src/Zend/zend_hash.c:1133
#3  0x000000000072a6b8 in shutdown_executor () at /root/tmp/php-src/Zend/zend_execute_API.c:347
#4  0x000000000073ac17 in zend_deactivate () at /root/tmp/php-src/Zend/zend.c:883
#5  0x00000000006dface in php_request_shutdown (dummy=dummy@entry=0x0) at /root/tmp/php-src/main/main.c:1859
#6  0x0000000000484214 in main (argc=2, argv=0x7fffffffe078) at /root/tmp/php-src/sapi/cgi/cgi_main.c:2515
(gdb) print prev
$1 = (Bucket *) 0x801feff03ff0
(gdb) print prev->val
Cannot access memory at address 0x801feff04000
(gdb) print idx
$2 = 1725

The issue is apparently here:
658: while (Z_NEXT(prev->val) != idx) {

However, I am not sure if the fault lies in _zend_hash_del_el() itself or if _zend_hash_del_el() is being called with incorrect arguments.

An identical segmentation fault occurs when calling this WordPress index.php script through apache2 with PHP as a SAPI module.

The master PHP branch was compiled with the following options:

'./configure' '--prefix=/root/tmp/usr' '--build=x86_64-pc-linux-gnu' '--host=x86_64-pc-linux-gnu' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--datadir=/usr/share' '--sysconfdir=/etc' '--localstatedir=/var/lib' '--prefix=/usr/lib64/php7.0' '--mandir=/usr/lib64/php7.0/man' '--infodir=/usr/lib64/php7.0/info' '--libdir=/usr/lib64/php7.0/lib' '--with-libdir=lib64' '--without-pear' '--disable-maintainer-zts' '--enable-bcmath' '--with-bz2=/usr' '--enable-calendar' '--enable-ctype' '--with-curl=/usr' '--enable-dom' '--without-enchant' '--disable-exif' '--enable-fileinfo' '--enable-filter' '--disable-ftp' '--with-gettext=/usr' '--without-gmp' '--enable-hash' '--with-mhash=/usr' '--with-iconv' '--enable-intl' '--enable-ipv6' '--enable-json' '--without-kerberos' '--enable-libxml' '--with-libxml-dir=/usr' '--enable-mbstring' '--with-mcrypt=/usr' '--without-mssql' '--with-onig=/usr' '--with-openssl=/usr' '--with-openssl-dir=/usr' '--disable-pcntl' '--enable-phar' '--enable-pdo' '--enable-opcache' '--without-pgsql' '--enable-posix' '--with-pspell=/usr' '--without-recode' '--enable-simplexml' '--disable-shmop' '--without-snmp' '--disable-soap' '--enable-sockets' '--without-sqlite3' '--without-sybase-ct' '--disable-sysvmsg' '--disable-sysvsem' '--disable-sysvshm' '--without-fpm-systemd' '--without-tidy' '--enable-tokenizer' '--disable-wddx' '--enable-xml' '--enable-xmlreader' '--enable-xmlwriter' '--without-xmlrpc' '--without-xsl' '--enable-zip' '--with-zlib=/usr' '--disable-debug' '--enable-dba' '--without-cdb' '--with-db4=/usr' '--disable-flatfile' '--with-gdbm=/usr' '--disable-inifile' '--without-qdbm' '--with-freetype-dir=/usr' '--with-t1lib=/usr' '--disable-gd-jis-conv' '--with-jpeg-dir=/usr' '--with-png-dir=/usr' '--without-xpm-dir' '--without-vpx-dir' '--with-gd' '--with-imap=/usr' '--with-imap-ssl=/usr' '--with-mysql=/usr' '--with-mysqli=/usr/bin/mysql_config' '--with-mysql-sock=/var/run/mysqld/mysqld.sock' '--without-pdo-dblib' '--with-pdo-mysql=/usr' '--without-pdo-pgsql' '--without-pdo-sqlite' '--without-pdo-odbc' '--with-readline=/usr' '--without-libedit' '--without-mm' '--with-pic' '--with-pcre-regex=/usr' '--with-pcre-dir=/usr' '--with-config-file-path=/root/tmp/usr/etc' '--disable-embed' '--enable-cli' '--enable-cgi' '--enable-fpm' '--with-apxs2=/usr/sbin/apxs2' 'build_alias=x86_64-pc-linux-gnu' 'host_alias=x86_64-pc-linux-gnu'

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-20 15:33 UTC] laruence@php.net
could you please run wordpress index.php with valgrind..

like:

USE_ZEND_ALLOC=0 valgrind path-to-php/bin/php wordpress/index.php

and paste the output out?

thanks
 [2014-10-21 02:51 UTC] bugs at milos dot nz
==22449== Memcheck, a memory error detector
==22449== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==22449== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==22449== Command: sapi/cgi/php-cgi /home/user/example.com/www/public_html/index.php
==22449==
X-Powered-By: PHP/7.0.0-dev
... snip ...
... more headers here ...
... snip ...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
... snip ...
... wordpress output here ...
... snip ...
</tr>
</table><!-- / layout -->
</div><!-- / container -->
</div><!-- / wrapper -->
</body>
</html>==22420== Invalid read of size 4
==22420==    at 0x745669: _zend_hash_del_el (zend_hash.c:658)
==22420==    by 0x745669: zend_hash_apply_deleter (zend_hash.c:973)
==22420==    by 0x74A218: zend_hash_reverse_apply (zend_hash.c:1133)
==22420==    by 0x7299E7: shutdown_executor (zend_execute_API.c:347)
==22420==    by 0x739DA6: zend_deactivate (zend.c:883)
==22420==    by 0x6DEDFD: php_request_shutdown (main.c:1859)
==22420==    by 0x483513: main (cgi_main.c:2515)
==22420==  Address 0x200e712e1c is not stack'd, malloc'd or (recently) free'd
==22420==
==22420==
==22420== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==22420==  Access not within mapped region at address 0x200E712E1C
==22420==    at 0x745669: _zend_hash_del_el (zend_hash.c:658)
==22420==    by 0x745669: zend_hash_apply_deleter (zend_hash.c:973)
==22420==    by 0x74A218: zend_hash_reverse_apply (zend_hash.c:1133)
==22420==    by 0x7299E7: shutdown_executor (zend_execute_API.c:347)
==22420==    by 0x739DA6: zend_deactivate (zend.c:883)
==22420==    by 0x6DEDFD: php_request_shutdown (main.c:1859)
==22420==    by 0x483513: main (cgi_main.c:2515)
==22420==  If you believe this happened as a result of a stack
==22420==  overflow in your program's main thread (unlikely but
==22420==  possible), you can try to increase the size of the
==22420==  main thread stack using the --main-stacksize= flag.
==22420==  The main thread stack size used in this run was 8388608.
==22420==
==22420== HEAP SUMMARY:
==22420==     in use at exit: 8,710,274 bytes in 68,379 blocks
==22420==   total heap usage: 463,170 allocs, 394,791 frees, 170,725,487 bytes allocated
==22420==
==22420== LEAK SUMMARY:
==22420==    definitely lost: 18,056 bytes in 367 blocks
==22420==    indirectly lost: 13,600 bytes in 28 blocks
==22420==      possibly lost: 6,328 bytes in 17 blocks
==22420==    still reachable: 8,672,290 bytes in 67,967 blocks
==22420==         suppressed: 0 bytes in 0 blocks
==22420== Rerun with --leak-check=full to see details of leaked memory
==22420==
==22420== For counts of detected and suppressed errors, rerun with: -v
==22420== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
 [2014-10-21 09:34 UTC] laruence@php.net
hmmm, could you please use bt -full ?

I needs to see what i is, and what ht->arData is

thanks
 [2014-10-21 10:10 UTC] bugs at milos dot nz
"i" is optimised out and I see no mention of "arData". I will try and recompile with -O0 when I find the appropriate setting in the Makefile and then I'll post my findings here. In the meantime, this is the output of `bt full` (with -O2, I *think*) in gdb:

(gdb) bt full
#0  _zend_hash_del_el (p=0x7fffeff117b0, idx=1725, ht=0xf7f880) at /root/tmp/php-src/Zend/zend_hash.c:658
        nIndex = 643
        i = <optimized out>
        prev = 0x801feff03ff0
#1  zend_hash_apply_deleter (ht=ht@entry=0xf7f880, idx=idx@entry=1725, p=p@entry=0x7fffeff117b0) at /root/tmp/php-src/Zend/zend_hash.c:973
No locals.
#2  0x000000000074a219 in zend_hash_reverse_apply (ht=0xf7f880, apply_func=apply_func@entry=0x729210 <clean_non_persistent_function>) at /root/tmp/php-src/Zend/zend_hash.c:1133
        idx = 1725
        p = 0x7fffeff117b0
        result = 1
#3  0x00000000007299e8 in shutdown_executor () at /root/tmp/php-src/Zend/zend_execute_API.c:347
        __orig_bailout = 0x7fffffffddc0
        __bailout = {{__jmpbuf = {163, -5169695161297403702, 140737488347264, 1, 17475568, 54, 5169695577156354250, -5169695152520429366}, __mask_was_saved = 0, __saved_mask = {__val = {13277048765369942218, 4294967296,
                13277048817496228042, 0, 16230304, 16217536, 5950268, 0, 16605696, 140737228258144, 1, 16230768, 16232032, 1, 7569822, 16231936}}}}
        func = <optimized out>
        ce = <optimized out>
#4  0x0000000000739da7 in zend_deactivate () at /root/tmp/php-src/Zend/zend.c:883
No locals.
#5  0x00000000006dedfe in php_request_shutdown (dummy=dummy@entry=0x0) at /root/tmp/php-src/main/main.c:1859
        report_memleaks = 1 '\001'
#6  0x0000000000483514 in main (argc=2, argv=0x7fffffffe078) at /root/tmp/php-src/sapi/cgi/cgi_main.c:2515
        __orig_bailout = 0x0
        __bailout = {{__jmpbuf = {0, -5169695578150403894, 4737515, 140737488347248, 0, 0, 5169695577051496650, -5169694958687092534}, __mask_was_saved = 0, __saved_mask = {__val = {140737488346912, 46, 140737354015960, 0,
                140737353971216, 140737353975024, 4472388, 140737229643112, 4276008, 4294967296, 4294969391, 140737229617936, 140737353971216, 140737488347072, 140737354130592, 140737488347112}}}}
        free_query_string = 1
        exit_status = 0
        cgi = 0
        c = <optimized out>
        i = <optimized out>
        len = <optimized out>
        file_handle = {handle = {fd = -261734144, fp = 0x7ffff0664100, stream = {handle = 0x7ffff0664100, isatty = 0, mmap = {len = 418, pos = 0, map = 0x0, buf = 0x7ffff7ff6000 "", old_handle = 0x0, old_closer = 0x0},
              reader = 0x6f6360 <_php_stream_read>, fsizer = 0x6dc7b0 <php_zend_stream_fsizer>, closer = 0x6dc790 <php_zend_stream_mmap_closer>}}, filename = 0x7ffff0602000 " \rh\360\377\177", opened_path = 0x0,
          type = ZEND_HANDLE_MAPPED, free_filename = 0 '\000'}
        s = <optimized out>
        behavior = 1
        no_headers = <optimized out>
        orig_optind = 1
        orig_optarg = 0x0
        script_file = <optimized out>
        ini_entries_len = <optimized out>
        max_requests = 500
        requests = 0
        fastcgi = 0
        bindpath = <optimized out>
        fcgi_fd = <optimized out>
        request = 0x0
        warmup_repeats = 0
        repeats = 1
        benchmark = <optimized out>
        start = {tv_sec = 140733193388093, tv_usec = 140737314330200}
        end = {tv_sec = 1, tv_usec = 140737351931677}
        status = 0
        query_string = <optimized out>
        decoded_query_string = <optimized out>
        skip_getopt = <optimized out>
 [2014-10-21 10:19 UTC] bugs at milos dot nz
The latest master PHP branch recompiled sans optimisation (-O0) results in the following gdb backtrace:

(gdb) bt full
#0  0x0000000000974b73 in _zend_hash_del_el (p=0x7fffeff117b0, idx=1725, ht=0x129c880) at /root/tmp/php-src/Zend/zend_hash.c:658
        nIndex = 643
        i = 4294967295
        prev = 0x801feff03ff0
#1  zend_hash_apply_deleter (ht=0x129c880, idx=1725, p=0x7fffeff117b0) at /root/tmp/php-src/Zend/zend_hash.c:973
No locals.
#2  0x00000000009753c7 in zend_hash_reverse_apply (ht=0x129c880, apply_func=0x93313a <clean_non_persistent_function>) at /root/tmp/php-src/Zend/zend_hash.c:1133
        idx = 1725
        p = 0x7fffeff117b0
        result = 1
#3  0x0000000000933da1 in shutdown_executor () at /root/tmp/php-src/Zend/zend_execute_API.c:347
        __orig_bailout = 0x7fffffffddf0
        __bailout = {{__jmpbuf = {0, -8375293845698859549, 4721632, 140737488347248, 0, 0, -8375293845684179485, 8375292634278702563}, __mask_was_saved = 0, __saved_mask = {__val = {140737226576512, 9343290, 19498944, 140737488345520,
                18446744073447799296, 140737488345520, 9772479, 0, 139646304518208, 9343290, 19498944, 140737226211328, 19498944, 140737488345552, 9343543, 140737226604240}}}}
        func = 0x129c830
        ce = 0x176eee0
#4  0x0000000000954b71 in zend_deactivate () at /root/tmp/php-src/Zend/zend.c:883
No locals.
#5  0x00000000008ab3d6 in php_request_shutdown (dummy=0x0) at /root/tmp/php-src/main/main.c:1859
        report_memleaks = 1 '\001'
#6  0x0000000000ad5df5 in main (argc=2, argv=0x7fffffffe078) at /root/tmp/php-src/sapi/cgi/cgi_main.c:2515
        __orig_bailout = 0x0
        __bailout = {{__jmpbuf = {0, -8375293845908574749, 4721632, 140737488347248, 0, 0, -8375293845814202909, 8375292580019351011}, __mask_was_saved = 0, __saved_mask = {__val = {4478074, 140737229643112, 4277064, 4294967296,
                4294969391, 140737229617936, 140737353971192, 140737488347072, 140737354130592, 140737488347112, 140737354129736, 1, 140737351931677, 0, 140737353971192, 1}}}}
        free_query_string = 1
        exit_status = 0
        cgi = 0
        c = -1
        i = 2
        len = 54
        file_handle = {handle = {fd = -261734144, fp = 0x7ffff0664100, stream = {handle = 0x7ffff0664100, isatty = 0, mmap = {len = 418, pos = 0, map = 0x0, buf = 0x7ffff7ff6000 "", old_handle = 0x0, old_closer = 0x0},
              reader = 0x8cb19a <_php_stream_read>, fsizer = 0x8aa26b <php_zend_stream_fsizer>, closer = 0x8aa245 <php_zend_stream_mmap_closer>}}, filename = 0x7ffff0602000 " \rh\360\377\177", opened_path = 0x0,
          type = ZEND_HANDLE_MAPPED, free_filename = 0 '\000'}
        s = 0x13c77f0 "/home/simon/theibguide.com/www/public_html/index.php"
        behavior = 1
        no_headers = 0
        orig_optind = 1
        orig_optarg = 0x0
        script_file = 0x0
        ini_entries_len = 0
        max_requests = 500
        requests = 0
        fastcgi = 0
        bindpath = 0x0
        fcgi_fd = 0
        request = 0x0
        warmup_repeats = 0
        repeats = 1
        benchmark = 0
        start = {tv_sec = 140737229643112, tv_usec = 140737314262832}
        end = {tv_sec = 1, tv_usec = 140737354129736}
        status = 0
        query_string = 0x0
        decoded_query_string = 0x7ffff7de5594 <do_lookup_x+2324> "H\205\300L\213L$\030L\213\\$(D\213D$0\017\205\216\370\377\377H\213T$\020\213\n\353\203ff.\017\037\204"
        skip_getopt = 0
 [2014-10-22 03:55 UTC] laruence@php.net
the i is IVALID_IDX here..... now the problem is how it became that...
 [2014-10-22 06:16 UTC] laruence@php.net
is that possible, you can grant me a remote access to your box ?

if yes, please send to me via mail :)

thanks
 [2014-10-22 06:17 UTC] laruence@php.net
is that possible, you can grant me a remote access to your box ?

if yes, please send to me via mail :)

thanks
 [2014-10-22 07:21 UTC] bugs at milos dot nz
Yes, that is fine. I will contact you sometime tomorrow or the day after. Thank you for your interest in this bug.
 [2014-10-22 08:58 UTC] laruence@php.net
great, thanks, a temporary access is enough :)
 [2014-10-25 06:14 UTC] bugs at milos dot nz
I have been able to replicate this on an isolated system with one of the affected WordPress installs. The issue seems to be directly related to opcache being loaded. With 'zend_extension=opcache.so' commented out in php.ini, the segmentation fault no longer occurs.

For the record, the php.ini file was the same as that recommended on the official PHP wiki (https://wiki.php.net/phpng):

max_execution_time=600
memory_limit=128M
error_reporting=E_ALL & ~E_NOTICE
display_errors=1
log_errors=1
user_ini.filename=
realpath_cache_size=2M
cgi.check_shebang_line=0
upload_max_filesize = 1024M
post_max_size = 1024M

zend_extension=opcache.so
opcache.enable_cli=1
opcache.save_comments=0
opcache.fast_shutdown=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.use_cwd=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=5
opcache.memory_consumption=128
opcache.consistency_checks=0

I have e-mailed you root access to an isolated virtual machine containing the WordPress install that exhibits this bug.
 [2014-10-28 07:20 UTC] laruence@php.net
Hey:
  I am sorry for didn't response to you.

  but what mail address you sent to?  I did't receive it :<

  please send to laruence at php.net  thanks
 [2014-10-28 07:25 UTC] bugs at milos dot nz
Hi,

It was sent successfully as per the mail log:
Oct 26 17:39:20 eclipse postfix/smtp[9607]: A071E265508: to=<laruence [at] php.net>, relay=osu1php.osuosl.org[140.211.15.143]:25, delay=4.9, delays=0.02/0.01/3.8/1, dsn=2.0.0, status=sent (250 OK 4D/00-02829-5FA7C445)

I will send it again for you.
 [2014-10-28 09:07 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2014-10-28 09:07 UTC] laruence@php.net
thanks for your help, I have made a reproduce script
<?php
function a() {
}

create_function('', 'var_dump("22");');

a();


I will fix it soon
 [2014-10-28 09:36 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e6fe3127d0e02a58456fef1af969a8f114f85c31
Log: Fixed bug #68252 (segfault in Zend/zend_hash.c in function _zend_hash_del_el)
 [2014-10-28 09:36 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 [2014-11-18 20:34 UTC] ab@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e6fe3127d0e02a58456fef1af969a8f114f85c31
Log: Fixed bug #68252 (segfault in Zend/zend_hash.c in function _zend_hash_del_el)
 [2016-07-20 11:40 UTC] davey@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e6fe3127d0e02a58456fef1af969a8f114f85c31
Log: Fixed bug #68252 (segfault in Zend/zend_hash.c in function _zend_hash_del_el)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 08:01:28 2024 UTC