php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #27070 preg_match() crashes Apache on VERY SIMPLE pattern but large subject size
Submitted: 2004-01-28 06:16 UTC Modified: 2004-01-29 13:43 UTC
From: pages at inrp dot fr Assigned:
Status: Not a bug Package: Reproducible crash
PHP Version: 5.0.0b3 (beta3) OS: Fedora Core 1 (Linux)
Private report: No CVE-ID:
 [2004-01-28 06:16 UTC] pages at inrp dot fr
Description:
------------
After running the script bellow, /var/log/httpd/error_log
says:

 [Wed Jan 28 00:19:30 2004] [notice] child pid 13744 exit signal Segmentation fault (11)

It has been tested on 3 different system :
 - Red Hat 8.0 + Apache 2.0.40 + PHP 4.2.2
 - Red Hat 9 + Apache 2.0.40 + PHP 4.2.2
 - Fedora Core 1 + Apache 2.0.48 + 5.0.0b3

Some statistics :
  - with pattern "/(a)*/", it crashes with a subject
    length > 13800
  - with pattern "/((a))*/", it crashes with a subject
    length > 9200
  - with pattern "/(((a)))*/", it crashes with a subject
    length > 6900
  - with pattern "/((((a))))*/", it crashes with a subject
    length > 5600
  - with pattern "/(((((a)))))*/", it crashes with a
    subject length > 4600
  - with pattern "/((((((a))))))*/", it crashes with a
    subject length > 4000
  - etc...


Reproduce code:
---------------
<?php
# This script crashes Apache :

$subject = str_repeat("a",13800);
preg_match("/(a)*/",$subject);
echo "OK";

# NB: The length of $subject (here 13800) may depend on
# your system. It seems to be related to the memory_limit
# directive (mine is 8M) but not in the way that
# one would expect (it doesn't seem to be something
# like "If I give more memory, then I need a larger
# subject to crash Apache").
# It doesn't crash if I use the pattern "/a*/" instead
# of "/(a)*/".
?>


Expected result:
----------------
No crash

Actual result:
--------------
Crash :-(

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-01-28 07:58 UTC] derick@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a backtrace to see what is happening behind the scenes. To
find out how to generate a backtrace, please read
http://bugs.php.net/bugs-generating-backtrace.php

Once you have generated a backtrace, please submit it to this bug
report and change the status back to "Open". Thank you for helping
us make PHP better.
 [2004-01-29 00:29 UTC] sniper@php.net
This is PCRE limitation. See also: http://www.pcre.org/pcre.txt

 [2004-01-29 13:43 UTC] pages at inrp dot fr
I agree every function has its own limitations. And if you
know them, then you can do some checkings on the values of
the parameters you want to pass to the function BEFORE to
call it.
So let's see what http://www.pcre.org/pcre.txt says
about the PCRE library limitations :

 1. "The maximum length of a compiled pattern is 65539".

   The length of my pattern is 4. I suppose the
   "compiled pattern" will be OK. (But what is exactly
   a "compiled pattern" ? And how can I know in advance
   the length it will have ?)

 2. "All values in repeating quantifiers must be less
    than 65536".

   I don't use any repeating quantifiers. OK.

 3. "The maximum number of capturing subpatterns is 65535".

   I have only one. OK.

 4. "The maximum depth of nesting parenthesized subpattern
    is 200".

   Here the depth is 1. OK.

 5. "The maximum length of a subject string is the largest
    positive number that an integer variable can hold".

   My subject has a length of 13800 so it's OK.

 6. "However, PCRE uses recursion to handle subpatterns
    and indefinite  repetition.  This  means  that the
    available stack space may limit the size of a subject
    string that can be processed  by certain patterns."

   So this could be the reason why I get a segmentation
   fault? That's why I tried to set memory_limit to
   64M in php.ini so my script should have enough
   available stack space. But it still crashes !
   (with the same subject size i.e. 13800)
   Anyway, shouldn't we get something like :

     Fatal error: Allowed memory size of 8388608 bytes
     exhausted (tried to allocate 13801 bytes) in
     crashme.php on line 5

   instead of a seg fault + crash ?
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 12:01:59 2014 UTC