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

[perl #129061] Valgrind: Buffer overrun in S_regmatch withpathological regular expression

Thread Previous
From:
Dan Collins
Date:
August 24, 2016 02:49
Subject:
[perl #129061] Valgrind: Buffer overrun in S_regmatch withpathological regular expression
Message ID:
rt-4.0.24-5316-1472006937-902.129061-75-0@perl.org
# New Ticket Created by  Dan Collins 
# Please include the string:  [perl #129061]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=129061 >


Detected using AFL and libdislocator, but reproducible with valgrind and an uninstrumented perl. 

The following regex causes a length-1 buffer to be allocated, but the second element of that buffer to be read, at two different points in S_regmatch. The buffer in question is reginfo->info_aux->poscache:

perl -e '/0*()*(||0(?0))^*0^+|(?0)(?0)/'

The only visible output of this script is the message:

But under debugging tools:

%% VALGRIND %%

==40309== Invalid read of size 1
==40309==    at 0xCB7E52: S_regmatch (regexec.c:7471)
==40309==    by 0xCB7E52: S_regtry (regexec.c:3619)
==40309==    by 0xD1A01D: Perl_regexec_flags (regexec.c:3486)
==40309==    by 0x8FD147: Perl_pp_match (pp_hot.c:1836)
==40309==    by 0x7E0833: Perl_runops_debug (dump.c:2234)
==40309==    by 0x53A0D8: S_run_body (perl.c:2525)
==40309==    by 0x53A0D8: perl_run (perl.c:2448)
==40309==    by 0x429A47: main (perlmain.c:123)
==40309==  Address 0x61bc8c1 is 0 bytes after a block of size 1 alloc'd
==40309==    at 0x4C2A986: calloc (vg_replace_malloc.c:711)
==40309==    by 0x7EFCAC: Perl_safesyscalloc (util.c:440)
==40309==    by 0xCEAD24: S_regmatch (regexec.c:7453)
==40309==    by 0xCEAD24: S_regtry (regexec.c:3619)
==40309==    by 0xD1A01D: Perl_regexec_flags (regexec.c:3486)
==40309==    by 0x8FD147: Perl_pp_match (pp_hot.c:1836)
==40309==    by 0x7E0833: Perl_runops_debug (dump.c:2234)
==40309==    by 0x53A0D8: S_run_body (perl.c:2525)
==40309==    by 0x53A0D8: perl_run (perl.c:2448)
==40309==    by 0x429A47: main (perlmain.c:123)
==40309==
==40309== Invalid read of size 1
==40309==    at 0xCC153D: S_regmatch (regexec.c:7519)
==40309==    by 0xCC153D: S_regtry (regexec.c:3619)
==40309==    by 0xD1A01D: Perl_regexec_flags (regexec.c:3486)
==40309==    by 0x8FD147: Perl_pp_match (pp_hot.c:1836)
==40309==    by 0x7E0833: Perl_runops_debug (dump.c:2234)
==40309==    by 0x53A0D8: S_run_body (perl.c:2525)
==40309==    by 0x53A0D8: perl_run (perl.c:2448)
==40309==    by 0x429A47: main (perlmain.c:123)
==40309==  Address 0x61bc8c1 is 0 bytes after a block of size 1 alloc'd
==40309==    at 0x4C2A986: calloc (vg_replace_malloc.c:711)
==40309==    by 0x7EFCAC: Perl_safesyscalloc (util.c:440)
==40309==    by 0xCEAD24: S_regmatch (regexec.c:7453)
==40309==    by 0xCEAD24: S_regtry (regexec.c:3619)
==40309==    by 0xD1A01D: Perl_regexec_flags (regexec.c:3486)
==40309==    by 0x8FD147: Perl_pp_match (pp_hot.c:1836)
==40309==    by 0x7E0833: Perl_runops_debug (dump.c:2234)
==40309==    by 0x53A0D8: S_run_body (perl.c:2525)
==40309==    by 0x53A0D8: perl_run (perl.c:2448)
==40309==    by 0x429A47: main (perlmain.c:123)
==40309==

%% GDB SESSION %%

Starting program: /home/dcollins/toolchain/perl/perl allcrash/f3i000025
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 3, S_regmatch (reginfo=0x7fffffffe070, startpos=0x80255f "",
    prog=0xac70a0) at regexec.c:7442
%% Size determined here %%
7442                        const SSize_t size = (reginfo->poscache_maxiter + 7)/8;
(gdb) p reginfo->poscache_maxiter
$2 = 3
(gdb) s
7443                        regmatch_info_aux *const aux = reginfo->info_aux;
(gdb) p size
$3 = 1
(gdb) c
Continuing.

Breakpoint 2, S_regmatch (reginfo=0x7fffffffe070, startpos=0x80255f "",
    prog=0xac70a0) at regexec.c:7453
%% Allocated here %%
7453                            Newxz(aux->poscache, size, char);
(gdb) p size
$4 = 1
(gdb) n
7455                        DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
(gdb) p *aux
$5 = {info_aux_eval = 0x0, old_regmatch_state = 0xac2450,
  old_regmatch_slab = 0xac2450, poscache = 0xab4060 ""}
(gdb) c
Continuing.

Breakpoint 1, S_regmatch (reginfo=0x7fffffffe070, startpos=0x80255f "",
    prog=0xac70a0) at regexec.c:7471
7471                        if (reginfo->info_aux->poscache[offset] & mask) {
(gdb) p offset
$6 = 1
(gdb) l
7466                        offset  = (scan->flags & 0xf) - 1
7467                                    +   (locinput - reginfo->strbeg)
7468                                      * (scan->flags>>4);
%% offset == 10 %%
7469                        mask    = 1 << (offset % 8);
7470                        offset /= 8;
%% offset == 1 %%
%% Segfaults/reads past the end of the buffer here: %%
7471                        if (reginfo->info_aux->poscache[offset] & mask) {
7472                            DEBUG_EXECUTE_r( Perl_re_exec_indentf( aTHX_  "whilem: (cache) already tried at this position...\n",
7473                                depth)
7474                            );
7475                            sayNO; /* cache records failure */
(gdb) p scan->flags
$7 = 59 ';'
(gdb) p reginfo->strbeg
$8 = 0x80255f ""
(gdb) p locinput
$9 = 0x80255f ""
(gdb) p offset
$10 = 1
(gdb) b regexec.c:7519
Breakpoint 4 at 0x6e0132: file regexec.c, line 7519.
(gdb) c
Continuing.

Breakpoint 4, S_regmatch (reginfo=0x7fffffffe070, startpos=0x80255f "",
    prog=0xac70a0) at regexec.c:7519
7519                CACHEsayNO;
(gdb) l
7514
7515            case WHILEM_B_max_fail: /* just failed to match B in a maximal match */
7516                cur_curlyx = ST.save_curlyx;
7517                cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
7518                cur_curlyx->u.curlyx.count--;
%% And again here: %%
7519                CACHEsayNO;
7520                NOT_REACHED; /* NOTREACHED */
7521
7522            case WHILEM_A_min_fail: /* just failed to match A in a minimal match */
7523                /* FALLTHROUGH */
(gdb)


-- 
Respectfully,
Dan Collins


Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About