php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39016 Segfault in preg_replace_impl
Submitted: 2006-10-02 15:30 UTC Modified: 2007-10-11 13:57 UTC
Votes:3
Avg. Score:4.3 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (50.0%)
From: jan at horde dot org Assigned: andrei (profile)
Status: Closed Package: PCRE related
PHP Version: 5.2.0RC4 OS: Linux
Private report: No CVE-ID: None
 [2006-10-02 15:30 UTC] jan at horde dot org
Description:
------------
Using preg_replace to parse and process email address in certain email message headers causes reproducable segfaults. Unfortunately these don't happen in a stripped down preg_replace call, but only in the context of a larger application. I was able to get a backtrace though that might be helpful:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1210352992 (LWP 32029)]
0xb75f8ca7 in preg_replace_impl (ht=<value optimized out>,
    return_value=0xb6560604, return_value_ptr=<value optimized out>,
    this_ptr=0x0, return_value_used=1, is_callable_replace=0 '\0')
    at /home/jan/software/php-5.2.0RC4/ext/pcre/php_pcre.c:1307
1307                                    switch(zend_hash_get_current_key(Z_ARRVAL_PP(subject), &string_key, &num_key, 0))

(gdb) bt
#0  0xb75f8ca7 in preg_replace_impl (ht=<value optimized out>,
    return_value=0xb6560604, return_value_ptr=<value optimized out>,
    this_ptr=0x0, return_value_used=1, is_callable_replace=0 '\0')
    at /home/jan/software/php-5.2.0RC4/ext/pcre/php_pcre.c:1307
#1  0xb78c0b6c in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf8090)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:200
#2  0xb78b3fbd in execute (op_array=0xb651143c)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#3  0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf8560)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#4  0xb78b3fbd in execute (op_array=0xb659a668)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#5  0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf8860)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#6  0xb78b3fbd in execute (op_array=0xb659b664)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#7  0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf8e40)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#8  0xb78b3fbd in execute (op_array=0xb65d7868)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#9  0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf8fa0)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#10 0xb78b3fbd in execute (op_array=0xb65d7798)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#11 0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf9850)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#12 0xb78b3fbd in execute (op_array=0xb66171b8)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#13 0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfaf9ab0)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#14 0xb78b3fbd in execute (op_array=0xb65d7934)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#15 0xb78c05eb in zend_do_fcall_common_helper_SPEC (execute_data=0xbfb00890)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:234
#16 0xb78b3fbd in execute (op_array=0xb6eb227c)
    at /home/jan/software/php-5.2.0RC4/Zend/zend_vm_execute.h:92
#17 0xb7898bb7 in zend_execute_scripts (type=8, retval=<value optimized out>,
    file_count=3) at /home/jan/software/php-5.2.0RC4/Zend/zend.c:1096
#18 0xb785b112 in php_execute_script (primary_file=0xbfb02bbc)
    at /home/jan/software/php-5.2.0RC4/main/main.c:1759
#19 0xb790f73f in apache_php_module_main (r=0x80d4434, display_source_mode=0)
    at /home/jan/software/php-5.2.0RC4/sapi/apache/sapi_apache.c:53
#20 0xb79106d8 in send_php (r=0x80d4434, display_source_mode=0, filename=0x0)
    at /home/jan/software/php-5.2.0RC4/sapi/apache/mod_php5.c:665
#21 0xb7910926 in send_parsed_php (r=0x80d4434)
    at /home/jan/software/php-5.2.0RC4/sapi/apache/mod_php5.c:680
#22 0x0806bd77 in ap_invoke_handler ()
#23 0x080823d9 in process_request_internal ()
#24 0x08082436 in ap_process_request ()
#25 0x08078b16 in child_main ()
#26 0x08078d4d in make_child ()
#27 0x08078ebd in startup_children ()
#28 0x0807958a in standalone_main ()
#29 0x08079e50 in main ()

The segfault happens in PHP 4 too.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-10-02 15:34 UTC] tony2001@php.net
Did you try fresh snapshots?
Do you see anything interesting with valgrind?
 [2006-10-02 15:36 UTC] jan at horde dot org
I should add the lines of code that caused this, right? :)


$regexp = <<<EOR
    /
    # Version 1: mailto: links with any valid email characters.
    # Pattern 1: Outlook parenthesizes in sqare brackets
    (\[\s*)?
    # Pattern 2: mailto: protocol prefix
    (mailto:\s?)
    # Pattern 3: email address
    ([^\s\?"<]*)
    # Pattern 4 to 6: Optional parameters
    ((\?)([^\s"<]*[\w+#?\/&=]))?
    # Pattern 7: Closing Outlook square bracket
    ((?(1)\s*\]))

    |
    # Version 2 Pattern 8: simple email addresses.
    (\b[\w-+.=]+@[-A-Z0-9.]*[A-Z0-9])
    # Pattern 9 to 11: Optional parameters
    ((\?)([^\s"<]*[\w+#?\/&=]))?

    /eix
EOR;

preg_replace($regexp,
             'Text_Filter_emails::callback(\'' . $tag . '\', \'' . $class . '\', \'$1\', \'$2\', \'$3\', \'$4\', \'$6\', \'$7\', \'$8\', \'$9\', \'$11\')',
             'a long list of email addresses etc.')

The regexp part that causes the problem, i.e. that no longer segfaults if removed is the pattern #8.
 [2006-10-02 15:41 UTC] jan at horde dot org
I didn't try a snapshot since this happens with PHP 4, so I guess it's an older issue that simply hasn't been triggered yet.

Here's the valgrind log:

==32185==  Address 0xBEDDDD32 is on thread 1's stack
==32185==
==32185== Invalid read of size 4
==32185==    at 0x449FCA7: preg_replace_impl (php_pcre.c:1307)
==32185==    by 0x4767B6B: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:200)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==  Address 0x1 is not stack'd, malloc'd or (recently) free'd
==32185==
==32185== Process terminating with default action of signal 11 (SIGSEGV)
==32185==  Access not within mapped region at address 0x1
==32185==    at 0x449FCA7: preg_replace_impl (php_pcre.c:1307)
==32185==    by 0x4767B6B: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:200)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==32185==    by 0x475AFBC: execute (zend_vm_execute.h:92)
==32185==    by 0x47675EA: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
 [2006-10-02 15:48 UTC] tony2001@php.net
What do you get in GDB with
p subject
p **subject
p string_key
p num_key
?
 [2006-10-02 15:51 UTC] jan at horde dot org
(gdb) p subject
$1 = (zval **) 0xb6f019e0
(gdb) p **subject
Cannot access memory at address 0x1
(gdb) p string_key
$2 = 0x10 <Address 0x10 out of bounds>
(gdb) p num_key
$3 = 1
 [2006-10-02 15:58 UTC] tony2001@php.net
Andrei, please take a look at this.
Looks like yet another stack overflow in PCRE..
 [2007-10-07 10:38 UTC] nlopess@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

your reproducing script isn't complete (I can't run it..)
 [2007-10-08 08:27 UTC] jan at horde dot org
The code is sufficient, because it segfaulted before it even was able to call the callback. But I can't reproduce this anymore with 5.2.3.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Nov 19 02:01:34 2019 UTC