develooper Front page | perl.perl5.porters | Postings from May 2016

[perl #128170] Assert fail in regcomp.c with no other symptoms: perl-e '/(?<=/'

Thread Next
Dan Collins
May 17, 2016 22:03
[perl #128170] Assert fail in regcomp.c with no other symptoms: perl-e '/(?<=/'
Message ID:
# New Ticket Created by  Dan Collins 
# Please include the string:  [perl #128170]
# in the subject line of all future correspondence about this issue. 
# <URL: >

Greetings Porters,

I have compiled bleadperl with the afl-gcc compiler using:

./Configure -Dusedevel -Dprefix='/usr/local/perl-afl' -Dcc='ccache afl-gcc' -Uuselongdouble -Duse64bitall -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -Dusequadmath -des
AFL_HARDEN=1 make && make test

And then fuzzed the resulting binary using:

AFL_NO_VAR_CHECK=1 afl-fuzz -i in -o out bin/perl @@

After reducing testcases using `afl-tmin` and performing additional minimization by hand, I have located the following testcase that triggers an assert fail in debugging builds of the perl interpreter. The testcase is the 6-character file:


On normal builds, this exits with the expected error. On debug builds, this returns an assert fail.

dcollins@nightshade64:~$ perl/miniperl -e '/(?<=/'
Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE ?<=/ at -e line 1.
dcollins@nightshade64:~$ perldebug/miniperl -e '/(?<=/'
miniperl: regcomp.c:10621: S_reg: Assertion `(pRExC_state->parse) < (pRExC_state->end)' failed.

Debugging tool output is below. A bisect was performed and points to the following diff:

cfbef7dc3bfb89e4ed2c00ea9c9e3bcfd0b170fd is the first bad commit
commit cfbef7dc3bfb89e4ed2c00ea9c9e3bcfd0b170fd
Author: Karl Williamson <>
Date:   Wed Feb 10 16:27:13 2016 -0700

    regcomp.c: Fix some parsing glitches

    I undertook a code review of how regcomp.c parses things in light of the
    tickets found by the fuzzer,  This commit is the
    result of my efforts so far.  I was not planning to push it now, but the
    work found a couple of new error messages that should be raised, and
    this has to be done before the visible changes code freeze coming up all
    too soon.  I will add test cases after that freeze, including if to see
    that these changes fix all the observed issues.

    The audit was tedious, and may have missed some things.  Several issues
    occurred in multiple places.  One is to not advance the parse by
    UTF8SKIP appropriately; another is to subtract one byte from the parse
    and assume that that is pointing to the beginning of the previous
    character (which under UTF-8 it may not).  Another is to assume that
    that the pattern is a C string, that there are no interior NULs in it.
    I also found unnecessary tests, given that an SV always has a
    terminating NUL.

:040000 040000 a58a2d3154c5e346f9dfab14f7ca9897cbe06cfb 41b83ee5e555d3ddc87935c3a3b30db821741214 M      pod
:100644 100644 c00fdffd93dd9de69326e9b567d912dd9a1bee3f aa06bc6e8da12440f5d5b649cd5faa24a8853cc7 M      regcomp.c
bisect run success


dcollins@nightshade64:~$ gdb --args perldebug/miniperl -e '/(?<=/'
GNU gdb (GDB) 7.10
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
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 "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from perldebug/miniperl...done.
(gdb) run
Starting program: /home/dcollins/perldebug/miniperl -e /\(\?\<=/
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/".
miniperl: regcomp.c:10621: S_reg: Assertion `(pRExC_state->parse) < (pRExC_state->end)' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff6cf9478 in raise () from /lib/x86_64-linux-gnu/
(gdb) bt
#0  0x00007ffff6cf9478 in raise () from /lib/x86_64-linux-gnu/
#1  0x00007ffff6cfa8fa in abort () from /lib/x86_64-linux-gnu/
#2  0x00007ffff6cf23a7 in ?? () from /lib/x86_64-linux-gnu/
#3  0x00007ffff6cf2452 in __assert_fail () from /lib/x86_64-linux-gnu/
#4  0x00000000006efe09 in S_reg (pRExC_state=0x7fffffffdcf0, paren=60, flagp=0x7fffffffd8bc, depth=5) at regcomp.c:10621
#5  0x00000000007186ed in S_regatom (pRExC_state=pRExC_state@entry=0x7fffffffdcf0, flagp=flagp@entry=0x7fffffffda34, depth=depth@entry=4) at regcomp.c:12354
#6  0x0000000000725d0d in S_regpiece (depth=<optimized out>, flagp=<synthetic pointer>, pRExC_state=0x7fffffffdcf0) at regcomp.c:11421
#7  S_regbranch (pRExC_state=pRExC_state@entry=0x7fffffffdcf0, flagp=flagp@entry=0x7fffffffdacc, first=first@entry=1, depth=depth@entry=2) at regcomp.c:11346
#8  0x0000000000745097 in S_reg (pRExC_state=pRExC_state@entry=0x7fffffffdcf0, flagp=flagp@entry=0x7fffffffdbbc, depth=1, paren=0) at regcomp.c:11084
#9  0x000000000077b231 in Perl_re_op_compile (patternp=<optimized out>, pat_count=<optimized out>, expr=<optimized out>, eng=0xf33160 <PL_core_reg_engine>, old_re=0x0,
    is_bare_re=<optimized out>, orig_rx_flags=0, pm_flags=0) at regcomp.c:7027
#10 0x00000000004c4033 in Perl_pmruntime (o=0x1202718, expr=0x12026d8, repl=0x0, isreg=isreg@entry=true, floor=<optimized out>) at op.c:5632
#11 0x000000000064b5cd in Perl_yyparse (gramtype=gramtype@entry=258) at perly.y:1028
#12 0x0000000000512111 in S_parse_body (xsinit=0xec1b00 <xs_init>, env=0x0) at perl.c:2365
#13 perl_parse (my_perl=<optimized out>, xsinit=xsinit@entry=0xec1b00 <xs_init>, argc=<optimized out>, argv=<optimized out>, env=env@entry=0x0) at perl.c:1681
#14 0x000000000040f838 in main (argc=<optimized out>, argv=<optimized out>, env=<optimized out>) at miniperlmain.c:120
(gdb) f 4
#4  0x00000000006efe09 in S_reg (pRExC_state=0x7fffffffdcf0, paren=60, flagp=0x7fffffffd8bc, depth=5) at regcomp.c:10621
10621                   assert(RExC_parse < RExC_end);
(gdb) info locals
is_logical = false
seqstart = <optimized out>
endptr = 0x0
has_intervening_patws = false
ret = 0x0
br = <optimized out>
lastbr = <optimized out>
ender = 0x0
parno = 0
flags = 0
oregflags = 0
have_branch = false
is_open = false
freeze_paren = 0
after_freeze = 0
num = <optimized out>
parse_start = 0x1202861 "?<="
oregcomp_parse = 0x1202861 "?<="
re_debug_flags = 0
(gdb) l
10616                       goto capturing_parens;
10617                   }
10618                   RExC_seen |= REG_LOOKBEHIND_SEEN;
10619                   RExC_in_lookbehind++;
10620                   RExC_parse++;
10621                   assert(RExC_parse < RExC_end);
10622                   /* FALLTHROUGH */
10623               case '=':           /* (?=...) */
10624                   RExC_seen_zerolen++;
10625                   break;

**PERL -V**

dcollins@nightshade64:~/perl$ ./perl -Ilib -V
Summary of my perl5 (revision 5 version 25 subversion 1) configuration:
  Commit id: 8255316ac82c0fbd7ae49f2f9a217ce063d7bbfb
    osname=linux, osvers=4.5.0-2-amd64, archname=x86_64-linux-ld
    uname='linux nightshade64 4.5.0-2-amd64 #1 smp debian 4.5.3-2 (2016-05-08) x86_64 gnulinux '
    config_args='-Dusedevel -Dprefix=/usr/local/perl-afl -Dcc=ccache afl-gcc -Duselongdouble -Duse64bitall -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=define, use64bitall=define, uselongdouble=define
    usemymalloc=n, bincompat5005=undef
    cc='ccache afl-gcc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion='', gccversion='6.1.0', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
    ivtype='long', ivsize=8, nvtype='long double', nvsize=16, Off_t='off_t', lseeksize=8
    alignbytes=16, prototype=define
  Linker and Libraries:
    ld='ccache afl-gcc', ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/local/lib/gcc/x86_64-pc-linux-gnu/6.1.0/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -g -L/usr/local/lib -fstack-protector-strong'

Characteristics of this binary (from libperl):
                        USE_64_BIT_ALL USE_64_BIT_INT USE_LARGE_FILES
                        USE_PERLIO USE_PERL_ATOF
  Built under linux
  Compiled at May 16 2016 07:45:27

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About