Bug 745475

Summary: segfault in preg_match when file/string with long line
Product: Red Hat Enterprise Linux 5 Reporter: Jani Ollikainen <bestis+rh>
Component: phpAssignee: Joe Orton <jorton>
Status: CLOSED WONTFIX QA Contact: BaseOS QE - Apps <qe-baseos-apps>
Severity: high Docs Contact:
Priority: unspecified    
Version: 5.7CC: bhubbard, rcollet
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-09-25 08:44:16 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Attachments:
Description Flags
Example file #1
none
Example file #2
none
Test program to segfault none

Description Jani Ollikainen 2011-10-12 13:32:17 UTC
Created attachment 527699 [details]
Example file #1

Description of problem:
Upgraded to new squirreilmail 1.4.22 as old one has fatal bug for me (https://bugzilla.redhat.com/show_bug.cgi?id=745469). But know found equally bad bug from PHP.

Doing simple preg_match will segfault with string with long line.

Version-Release number of selected component (if applicable):
php-5.1.6-27.el5_5.3

How reproducible:
Run example program

Steps to Reproduce:
1. Download files
2. Run program
  
Actual results:
nomatch
Segmentation fault

Expected results:
nomatch
nomatch

Additional info:

Comment 1 Jani Ollikainen 2011-10-12 13:32:50 UTC
Created attachment 527700 [details]
Example file #2

Comment 2 Jani Ollikainen 2011-10-12 13:33:20 UTC
Created attachment 527701 [details]
Test program to segfault

Comment 3 Brad Hubbard 2012-03-08 04:05:26 UTC
I managed to reproduce this with the latest php53-5.3.3-5.el5 (based on 5.3.3).

Core was generated by `php -f test.php'.
Program terminated with signal 11, Segmentation fault.
#0  0x0000003918a0c3d8 in match (eptr=0x16e45052 'a' <repeats 200 times>..., ecode=0x16e6b01a ";", offset_top=4, md=0x7fffed161800, ims=1, eptrb=0x7fffec565560, 
    flags=0, rdepth=13543) at ./pcre_exec.c:378

Our recursion depth is 13543 which is pretty deep.

(gdb) x/i 0x0000003918a0c3d8
0x3918a0c3d8 <match+72>:        mov    %edx,0x120(%rsp)

So the problem is when we dereference %rsp.

rsp            0x7fffec564e90 <-- Stack pointer (where we are on the stack).

(gdb) p/x 0x7fffec564e90+0x120
$4 = 0x7fffec564fb0
(gdb) x 0x7fffec564fb0
0x7fffec564fb0: Cannot access memory at address 0x7fffec564fb0 <-- Segfault

# ulimit -s
10240  <-- stack size in kilobytes

(gdb) p/d 10240*1024
$6 = 10485760 <-- size of the stack

rbp            0x7fffed161800 <-- Stack base pointer.

(gdb) p/d 0x7fffed161800-0x7fffec564fb0
$5 = 12568656

So we appear to have indexed off the end of the stack.

Sure enough setting;

# ulimit -s 20480
# php -f test.php 
nomatch
nomatch

works fine with both php53 and the latest php package and this is one workaround. The other workaround is to install php53 (you need to remove the standard php package first) and edit /etc/php.ini adding a line like so;

;pcre.recursion_limit=100000
pcre.recursion_limit=10000

This keeps the level of recursion under 10000 and stays within the resources of the stack (the problem being number of recursions vs. size of stack).

This has been discussed upstream https://bugs.php.net/bug.php?id=55090 https://bugs.php.net/bug.php?id=52818 and the devs have stated that they have no intention of fixing this. Given that fact and the available workarounds I suspect this BZ will end in WONTFIX but that is not my call to make.

Comment 4 Remi Collet 2012-09-25 08:44:16 UTC
Link to PHP documentation for this option, which include a comment about the possible crash:
http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit

As PHP project don't plan to fix this, and as workarounds exists, closing as WONTFIX.