In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/adc2d0c9de764f1cb892860df8ecc93dc8909b39?hp=608fe6e2ff595fc26cd6115e2040cb51154c6e45>
- Log ----------------------------------------------------------------- commit adc2d0c9de764f1cb892860df8ecc93dc8909b39 Author: Jarkko Hietaniemi <j...@iki.fi> Date: Mon Apr 21 21:43:12 2014 -0400 Fix for Coverity perl5 CID 29034: Out-of-bounds read (OVERRUN) overrun-local: Overrunning array PL_reg_intflags name of 14 8-byte elements at element index 31 (byte offset 248) using index bit (which evaluates to 31). Needed compile-time limits for the PL_reg_intflags_name so that the bit loop doesn't waltz off past the array. Could not use C_ARRAY_LENGTH because the size of name array is not visible during compile time (only const char*[] is), so modified regcomp.pl to generate the size, made it visible only under DEBUGGING. Did extflags analogously even though its size currently exactly 32 already. The sizeof(flags)*8 is extra paranoia for ILP64. M regcomp.c M regen/regcomp.pl M regnodes.h commit 2a600bb8f7c0d6b36cb37c899b6c9e82537ec394 Author: Jarkko Hietaniemi <j...@iki.fi> Date: Mon Apr 21 18:54:54 2014 -0400 Fix for Coverity perl5 CID 29060: Pointer to local outside scope (RETURN_LOCAL) use_invalid: Using mode, which points to an out-of-scope variable tmode. Duplicate the PerlIOBase_pushed call so that the tmode is in scope. M perlio.c commit 53673d98756218ddd125311548c0f73c714722f7 Author: Jarkko Hietaniemi <j...@iki.fi> Date: Mon Apr 21 18:15:58 2014 -0400 Fix for Coverity perl5 CID 29032: Out-of-bounds read (OVERRUN) overrun-local: Overrunning array anyofs of 34 8-byte elements at element index 34 (byte offset 272) using index index (which evaluates to 34). Off-by-one error: because the test "index > number of elements" should have used ">=", the anyofs[] could have been accessed one past the end. Use the C_ARRAY_LENGTH since we have it. I think regprop is only used by -Mre=debug. M regcomp.c ----------------------------------------------------------------------- Summary of changes: perlio.c | 1 + regcomp.c | 16 ++++++++++------ regen/regcomp.pl | 17 ++++++++++++++++- regnodes.h | 8 ++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/perlio.c b/perlio.c index 0ae0a43..d4c43d0 100644 --- a/perlio.c +++ b/perlio.c @@ -2905,6 +2905,7 @@ PerlIOStdio_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab PerlIOSelf(f, PerlIOStdio)->stdio = stdio; /* We never call down so do any pending stuff now */ PerlIO_flush(PerlIONext(f)); + return PerlIOBase_pushed(aTHX_ f, mode, arg, tab); } else { return -1; diff --git a/regcomp.c b/regcomp.c index ca2ffb8..920f7cb 100644 --- a/regcomp.c +++ b/regcomp.c @@ -15365,7 +15365,9 @@ S_regdump_intflags(pTHX_ const char *lead, const U32 flags) int bit; int set=0; - for (bit=0; bit<32; bit++) { + ASSUME(REG_INTFLAGS_NAME_SIZE <= sizeof(flags)*8); + + for (bit=0; bit<REG_INTFLAGS_NAME_SIZE; bit++) { if (flags & (1<<bit)) { if (!set++ && lead) PerlIO_printf(Perl_debug_log, "%s",lead); @@ -15387,7 +15389,9 @@ S_regdump_extflags(pTHX_ const char *lead, const U32 flags) int set=0; regex_charset cs; - for (bit=0; bit<32; bit++) { + ASSUME(REG_EXTFLAGS_NAME_SIZE <= sizeof(flags)*8); + + for (bit=0; bit<REG_EXTFLAGS_NAME_SIZE; bit++) { if (flags & (1<<bit)) { if ((1<<bit) & RXf_PMf_CHARSET) { /* Output separately, below */ continue; @@ -15831,10 +15835,7 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_ } else if (k == POSIXD || k == NPOSIXD) { U8 index = FLAGS(o) * 2; - if (index > (sizeof(anyofs) / sizeof(anyofs[0]))) { - Perl_sv_catpvf(aTHX_ sv, "[illegal type=%d])", index); - } - else { + if (index < C_ARRAY_LENGTH(anyofs)) { if (*anyofs[index] != '[') { sv_catpv(sv, "["); } @@ -15843,6 +15844,9 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_ sv_catpv(sv, "]"); } } + else { + Perl_sv_catpvf(aTHX_ sv, "[illegal type=%d])", index); + } } else if (k == BRANCHJ && (OP(o) == UNLESSM || OP(o) == IFMATCH)) Perl_sv_catpvf(aTHX_ sv, "[%d]", -(o->flags)); diff --git a/regen/regcomp.pl b/regen/regcomp.pl index 4a8b9d5..2b6d964 100644 --- a/regen/regcomp.pl +++ b/regen/regcomp.pl @@ -261,6 +261,7 @@ my %rxfv; my %definitions; # Remember what the symbol definitions are my $val = 0; my %reverse; +my $REG_EXTFLAGS_NAME_SIZE = 0; foreach my $file ("op_reg_common.h", "regexp.h") { open FH,"<$file" or die "Can't read $file: $!"; while (<FH>) { @@ -332,6 +333,7 @@ for (0..31) { s/\bRXf_(PMf_)?// for $n, $extra; printf $out qq(\t%-20s/* 0x%08x%s */\n), qq("$n",),$power_of_2, $extra; + $REG_EXTFLAGS_NAME_SIZE++; } print $out <<EOP; @@ -339,6 +341,12 @@ print $out <<EOP; #endif /* DOINIT */ EOP +print $out <<EOQ +#ifdef DEBUGGING +# define REG_EXTFLAGS_NAME_SIZE $REG_EXTFLAGS_NAME_SIZE +#endif + +EOQ } { print $out <<EOP; @@ -354,6 +362,7 @@ my %rxfv; my %definitions; # Remember what the symbol definitions are my $val = 0; my %reverse; +my $REG_INTFLAGS_NAME_SIZE = 0; foreach my $file ("regcomp.h") { open my $fh, "<", $file or die "Can't read $file: $!"; while (<$fh>) { @@ -369,6 +378,7 @@ foreach my $file ("regcomp.h") { $comment= $comment ? " - $comment" : ""; printf $out qq(\t%-30s/* 0x%08x - %s%s */\n), qq("$abbr",), $val, $define, $comment; + $REG_INTFLAGS_NAME_SIZE++; } } } @@ -378,8 +388,13 @@ print $out <<EOP; #endif /* DOINIT */ EOP -} +print $out <<EOQ; +#ifdef DEBUGGING +# define REG_INTFLAGS_NAME_SIZE $REG_INTFLAGS_NAME_SIZE +#endif +EOQ +} print $out process_flags('V', 'varies', <<'EOC'); /* The following have no fixed length. U8 so we can do strchr() on it. */ diff --git a/regnodes.h b/regnodes.h index 4f4ff9e..43ec681 100644 --- a/regnodes.h +++ b/regnodes.h @@ -676,6 +676,10 @@ EXTCONST char * const PL_reg_extflags_name[] = { }; #endif /* DOINIT */ +#ifdef DEBUGGING +# define REG_EXTFLAGS_NAME_SIZE 32 +#endif + /* PL_reg_intflags_name[] - Opcode/state names in string form, for debugging */ #ifndef DOINIT @@ -699,6 +703,10 @@ EXTCONST char * const PL_reg_intflags_name[] = { }; #endif /* DOINIT */ +#ifdef DEBUGGING +# define REG_INTFLAGS_NAME_SIZE 14 +#endif + /* The following have no fixed length. U8 so we can do strchr() on it. */ #define REGNODE_VARIES(node) (PL_varies_bitmask[(node) >> 3] & (1 << ((node) & 7))) -- Perl5 Master Repository