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

Reply via email to