infinite recursion in libpcre via PHP

Bug #334107 reported by Milian Wolff
22
This bug affects 4 people
Affects Status Importance Assigned to Milestone
pcre3 (Ubuntu)
New
Undecided
Unassigned

Bug Description

I get a segfault due to an infinite recursion in libpcre with the following PHP code:

~~~
<?php

// 7067 is the lowest len I get a segfault for
// below all is fine, everythinga bove crashes as well
// note: without the ' after \n this does not segfault either
$str = "<?php\n'".str_repeat("a", 7067);

// see php.php:1080 in GeSHi
$regexp = "/(<\?(?:php)?)(?:'(?:[^'\\\\]|\\\\.)*?'|\"(?:[^\"\\\\]|\\\\.)*?\"|\/\*(?!\*\/).*?\*\/|.)*?(\?>|\Z)/sm";

preg_match($regexp, $str);
~~~

Valgrind output:
~~~
$ valgrind php segfault.php
==16511== Memcheck, a memory error detector.
==16511== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==16511== Using LibVEX rev 1854, a library for dynamic binary translation.
==16511== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==16511== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==16511== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==16511== For more details, rerun with: -v
==16511==
==16511== Invalid read of size 4
==16511== at 0x4015827: (within /lib/ld-2.8.90.so)
==16511== by 0x46520A1: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x400D715: (within /lib/ld-2.8.90.so)
==16511== by 0x4652264: __libc_dlopen_mode (in /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x4629ADF: __nss_lookup_function (in /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x4629BAE: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x462BA1C: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x46325DD: getprotobyname_r (in /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x46323C6: getprotobyname (in /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x81D75F9: zm_startup_sockets (in /usr/bin/php5)
==16511== by 0x82E096D: zend_startup_module_ex (in /usr/bin/php5)
==16511== by 0x82E595C: zend_hash_apply (in /usr/bin/php5)
==16511== Address 0x490f8e4 is 44 bytes inside a block of size 46 alloc'd
==16511== at 0x4025D2E: malloc (vg_replace_malloc.c:207)
==16511== by 0x400D823: (within /lib/ld-2.8.90.so)
==16511== by 0x4008235: (within /lib/ld-2.8.90.so)
==16511== by 0x40118E6: (within /lib/ld-2.8.90.so)
==16511== by 0x400D715: (within /lib/ld-2.8.90.so)
==16511== by 0x40112ED: (within /lib/ld-2.8.90.so)
==16511== by 0x46520A1: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x400D715: (within /lib/ld-2.8.90.so)
==16511== by 0x4652264: __libc_dlopen_mode (in /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x4629ADF: __nss_lookup_function (in /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x4629BAE: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== by 0x462BA1C: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==16511== Stack overflow in thread 1: can't grow stack to 0xBE2BDDB8
==16511==
==16511== Process terminating with default action of signal 11 (SIGSEGV)
==16511== Access not within mapped region at address 0xBE2BDDB8
==16511== at 0x429CD2C: (within /lib/libpcre.so.3.12.1)
==16511== Stack overflow in thread 1: can't grow stack to 0xBE2BDC7C
==16511==
==16511== Process terminating with default action of signal 11 (SIGSEGV)
==16511== Access not within mapped region at address 0xBE2BDC7C
==16511== at 0x401F220: _vgnU_freeres (vg_preloaded.c:56)
==16511==
==16511== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 163 from 3)
==16511== malloc/free: in use at exit: 1,358,550 bytes in 17,289 blocks.
==16511== malloc/free: 18,480 allocs, 1,191 frees, 1,816,402 bytes allocated.
==16511== For counts of detected errors, rerun with: -v
==16511== searching for pointers to 17,289 not-freed blocks.
==16511== checked 11,377,616 bytes.
==16511==
==16511== LEAK SUMMARY:
==16511== definitely lost: 0 bytes in 0 blocks.
==16511== possibly lost: 144 bytes in 1 blocks.
==16511== still reachable: 1,358,406 bytes in 17,288 blocks.
==16511== suppressed: 0 bytes in 0 blocks.
==16511== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault
~~~

gdb output:
~~~
$ gdb php
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(no debugging symbols found)
(gdb) run segfault.php
Starting program: /usr/bin/php segfault.php
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
(no debugging symbols found)
[New Thread 0xb77688e0 (LWP 16588)]
[New Thread 0xb7148b90 (LWP 16591)]
[Thread 0xb7148b90 (LWP 16591) exited]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb77688e0 (LWP 16588)]
0xb7cabd2c in match (eptr=0xb773b7e4 "aa", ecode=0xa403a98 "\034'T", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7069) at pcre_exec.c:431
431 pcre_exec.c: No such file or directory.
        in pcre_exec.c
(gdb) bt
#0 0xb7cabd2c in match (eptr=0xb773b7e4 "aa", ecode=0xa403a98 "\034'T", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7069) at pcre_exec.c:431
#1 0xb7cb5bb5 in match (eptr=0xb773b7e4 "aa", ecode=0xa403a95 "W", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7068) at pcre_exec.c:1311
#2 0xb7cac0d9 in match (eptr=0xb773b7e3 "aaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7067) at pcre_exec.c:775
#3 0xb7cac0d9 in match (eptr=0xb773b7e2 "aaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7066) at pcre_exec.c:775
#4 0xb7cac0d9 in match (eptr=0xb773b7e1 "aaaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7065) at pcre_exec.c:775
#5 0xb7cac0d9 in match (eptr=0xb773b7e0 "aaaaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7064) at pcre_exec.c:775
#6 0xb7cac0d9 in match (eptr=0xb773b7df "aaaaaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6, eptrb=0x0,
    flags=0, rdepth=7063) at pcre_exec.c:775
#7 0xb7cac0d9 in match (eptr=0xb773b7de "aaaaaaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6,
    eptrb=0x0, flags=0, rdepth=7062) at pcre_exec.c:775
#8 0xb7cac0d9 in match (eptr=0xb773b7dd "aaaaaaaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6,
    eptrb=0x0, flags=0, rdepth=7061) at pcre_exec.c:775
#9 0xb7cac0d9 in match (eptr=0xb773b7dc "aaaaaaaaaa", ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738, ims=6,
    eptrb=0x0, flags=0, rdepth=7060) at pcre_exec.c:775
#10 0xb7cac0d9 in match (eptr=0xb773b7db 'a' <repeats 11 times>, ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738,
    ims=6, eptrb=0x0, flags=0, rdepth=7059) at pcre_exec.c:775
#11 0xb7cac0d9 in match (eptr=0xb773b7da 'a' <repeats 12 times>, ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738,
    ims=6, eptrb=0x0, flags=0, rdepth=7058) at pcre_exec.c:775
#12 0xb7cac0d9 in match (eptr=0xb773b7d9 'a' <repeats 13 times>, ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738,
    ims=6, eptrb=0x0, flags=0, rdepth=7057) at pcre_exec.c:775
#13 0xb7cac0d9 in match (eptr=0xb773b7d8 'a' <repeats 14 times>, ecode=0xa403a6b "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4, md=0xbfe47738,
    ims=6, eptrb=0x0, flags=0, rdepth=7056) at pcre_exec.c:775
~~~
The last line is repeated _many many_ times...
~~~
#7067 0xb7cac0d9 in match (eptr=0xb7739c4a "'", 'a' <repeats 199 times>..., ecode=0xa403a65 "^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=4,
    md=0xbfe47738, ims=6, eptrb=0x0, flags=0, rdepth=2) at pcre_exec.c:775
#7068 0xb7cacb64 in match (eptr=0xb7739c46 "php\n'", 'a' <repeats 195 times>..., ecode=0xa403a54 "g^", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=2,
    md=0xbfe47738, ims=6, eptrb=0x0, flags=<value optimized out>, rdepth=1) at pcre_exec.c:1186
#7069 0xb7cadd82 in match (eptr=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., ecode=0xa403a4b "_", mstart=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., offset_top=2,
    md=0xbfe47738, ims=6, eptrb=0x0, flags=0, rdepth=0) at pcre_exec.c:716
#7070 0xb7cb7207 in pcre_exec (argument_re=0xa403a20, extra_data=0xbfe478ec, subject=0xb7739c44 "<?php\n'", 'a' <repeats 193 times>..., length=7074, start_offset=0, options=0,
    offsets=0xb7737150, offsetcount=9) at pcre_exec.c:4846
#7071 0x080a8ec4 in php_pcre_match_impl ()
#7072 0x080a9a9c in ?? ()
#7073 0x082fb8b1 in execute_internal ()

#7074 0xb76bf9c4 in xdebug_execute_internal (current_execute_data=0xbfe47b98, return_value_used=0) at /tmp/pear/cache/xdebug-2.0.3/xdebug.c:1605
#7075 0x08314700 in ?? ()
#7076 0x082fff1b in execute ()
---Type <return> to continue, or q <return> to quit---
#7077 0xb76bf668 in xdebug_execute (op_array=0xb77368b8) at /tmp/pear/cache/xdebug-2.0.3/xdebug.c:1541
#7078 0x082da5c0 in zend_execute_scripts ()
#7079 0x0828ef2a in php_execute_script ()
#7080 0x0835ec24 in main ()
~~~

Information:
~~~
$ php --version
PHP 5.2.6-2ubuntu4.1 with Suhosin-Patch 0.9.6.2 (cli) (built: Feb 11 2009 20:38:24)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
~~~

excerpt of phpinfo():
~~~
pcre

PCRE (Perl Compatible Regular Expressions) Support => enabled
PCRE Library Version => 7.8 2008-09-05

Directive => Local Value => Master Value
pcre.backtrack_limit => 100000 => 100000
pcre.recursion_limit => 100000 => 100000
~~~

If you need more input, just let me know.

ProblemType: Bug
Architecture: i386
Dependencies:
 libgcc1 1:4.3.2-1ubuntu12
 gcc-4.3-base 4.3.2-1ubuntu12
 findutils 4.4.0-2ubuntu3
 libc6 2.8~20080505-0ubuntu9
DistroRelease: Ubuntu 8.10
NonfreeKernelModules: nvidia
Package: libpcre3 7.8-2ubuntu1~intrepid1~ppa1
ProcEnviron:
 LANGUAGE=de_DE:de:en_GB:en
 PATH=/home/username/projects/compiled/kde4/bin:/home/username/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
 LANG=de_DE.UTF-8
 SHELL=/bin/bash
SourcePackage: pcre3
Uname: Linux 2.6.27-11-generic i686
UnreportableReason: This is not a genuine Ubuntu package

Tags: apport-bug
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.