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