php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73490 segfault in match (pcre_exec.c)
Submitted: 2016-11-10 19:27 UTC Modified: 2016-11-18 12:10 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: brian dot carpenter at gmail dot com Assigned: cmb (profile)
Status: Not a bug Package: PCRE related
PHP Version: 5.6.28 OS: Debian 8.x
Private report: No CVE-ID: None
 [2016-11-10 19:27 UTC] brian dot carpenter at gmail dot com
Description:
------------
Found while fuzzing with AFL+ASan.

Test script:
---------------
<?php

$pattern = '(?(1)0|(?(1)0)+)+((()))';

$a = preg_match("/$pattern/", '2966');
var_dump($a);

Expected result:
----------------
No crash. For example, PHP 5.6.24-0+deb8u1 returns int(1).

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.
0x000000000060e47f in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8715) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:516
516     {
(gdb) list
511
512     static int
513     match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
514       PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
515       unsigned int rdepth)
516     {
517     /* These variables do not need to be preserved over recursion in this function,
518     so they can be ordinary variables in all cases. Mark some of them with
519     "register" because they are used a lot in loops. */
520
(gdb) bt
#0  0x000000000060e47f in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8715) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:516
#1  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8714) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#2  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8713) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#3  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8712) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#4  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8711) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#5  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8710) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#6  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8709) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#7  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8708) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#8  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8707) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
#9  0x000000000066b5a1 in match (eptr=0x7ffff7e63610 "2966", ecode=0x60c000006743 "\207", mstart=0x7ffff7e63610 "2966", offset_top=2,
    md=0x7fffffff9d40, eptrb=0x0, rdepth=8706) at /root/php-5.6.27/ext/pcre/pcrelib/pcre_exec.c:2061
and on and on for infinity...

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-10 21:07 UTC] brian dot carpenter at gmail dot com
-Summary: segfault in pcre_exec.c +Summary: segfault in match (pcre_exec.c) -PHP Version: 5.6.27 +PHP Version: 5.6.28
 [2016-11-10 21:07 UTC] brian dot carpenter at gmail dot com
Updated because it also crashes the recently released 5.6.28.
 [2016-11-18 12:10 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Package: Reproducible crash +Package: PCRE related -Assigned To: +Assigned To: cmb
 [2016-11-18 12:10 UTC] cmb@php.net
I can reproduce the segfault due to "infinite" recursion with the
default pcre.recursion_limit=100000. The script succeeds for me
with pcre.recursion_limit=25000, though. The result is than
correctly `bool(false)` and not `int(1)` which would be wrong.

I don't think this is a bug, because the regexp is
"pathological"[1], and pcre.recursion_limit is already
configurable.

[1] <https://swtch.com/~rsc/regexp/regexp1.html>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 07:01:27 2024 UTC