[perl] [cve-2007-5116] heap overflow
Bug #160693 reported by
disabled.user
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
perl (Ubuntu) |
Fix Released
|
Undecided
|
Stephan Rügamer | ||
Bug Description
Binary package hint: perl
References:
[1] http://
[2] Bug #160454
From [1]:
"Will Drewry and Tavis Ormandy of the Google Security Team have discovered a UTF-8 related heap overflow in Perl's regular expression compiler, probably allowing attackers to execute arbitrary code by compiling specially crafted regular expressions."
CVE References
Changed in perl: | |
assignee: | nobody → shermann |
status: | New → In Progress |
To post a comment you must log in.
The patch applied to the Perl core is the following...
==== //depot/ maint-5. 8/perl/ regcomp. c#109 (text) ====
@@ -117,7 +117,10 @@ state-> starttry) state-> seen_zerolen) state-> seen_evals) state-> orig_utf8)
I32 extralen;
I32 seen_zerolen;
I32 seen_evals;
- I32 utf8;
+ I32 utf8; /* whether the pattern is utf8 or not */
+ I32 orig_utf8; /* whether the pattern was originally in utf8 */
+ /* XXX use this for future optimisation of case
+ * where pattern must be upgraded to utf8. */
#if ADD_TO_REGEXEC
char *starttry; /* -Dr: where regtry was called. */
#define RExC_starttry (pRExC_
@@ -143,6 +146,7 @@
#define RExC_seen_zerolen (pRExC_
#define RExC_seen_evals (pRExC_
#define RExC_utf8 (pRExC_state->utf8)
+#define RExC_orig_utf8 (pRExC_
#define ISMULT1(c) ((c) == '*' || (c) == '+' || (c) == '?')
#define ISMULT2(s) ((*s) == '*' || (*s) == '+' || (*s) == '?' || \
@@ -1720,15 +1724,17 @@
if (exp == NULL)
FAIL("NULL regexp argument");
- RExC_utf8 = pm->op_pmdynflags & PMdf_CMP_UTF8;
+ RExC_utf8 = RExC_orig_utf8 = pm->op_pmdynflags & PMdf_CMP_UTF8;
- RExC_precomp = exp; printf( Perl_debug_ log, "%sCompiling REx%s `%s%*s%s'\n",
PL_colors[ 4],PL_colors[ 5],PL_colors[ 0],
(int) (xend - exp), RExC_precomp, PL_colors[1]); printf( Perl_debug_ log, "%sCompiling REx%s `%s%*s%s'\n",
PL_colors[ 4],PL_colors[ 5],PL_colors[ 0],
DEBUG_r({
if (!PL_colorset) reginitcolors();
PerlIO_
});
+
+redo_first_pass:
+ RExC_precomp = exp;
RExC_flags = pm->op_pmflags;
RExC_sawback = 0;
@@ -1730,7 +1730,7 @@
if (!PL_colorset) reginitcolors();
PerlIO_
- (int)(xend - exp), RExC_precomp, PL_colors[1]);
+ (int)(xend - exp), exp, PL_colors[1]);
});
redo_first_pass: PerlIO_ printf( Perl_debug_ log, Perl_bytes_ to_utf8( aTHX_ (U8*)exp, &len); r(PerlIO_ printf( Perl_debug_ log, "size %"IVdf" ", (IV)RExC_size));
@@ -1754,6 +1760,25 @@
RExC_precomp = NULL;
return(NULL);
}
+ if (RExC_utf8 && !RExC_orig_utf8) {
+ /* It's possible to write a regexp in ascii that represents unicode
+ codepoints outside of the byte range, such as via \x{100}. If we
+ detect such a sequence we have to convert the entire pattern to utf8
+ and then recompile, as our sizing calculation will have been based
+ on 1 byte == 1 character, but we will need to use utf8 to encode
+ at least some part of the pattern, and therefore must convert the whole
+ thing.
+ XXX: somehow figure out how to make this less expensive...
+ -- dmq */
+ STRLEN len = xend-exp;
+ DEBUG_r(
+ "UTF8 mismatch! Converting to utf8 for resizing and compile\n"));
+ exp = (char*)
+ xend = exp + len;
+ RExC_orig_utf8 = RExC_utf8;
+ SAVEFREEPV(exp);
+ goto redo_first_pass;
+ }
DEBUG_
/* Small enough for pointer-storage convention?
==== //depot/ maint-5. 8/perl/ t/op/pat. t#46 (xtext) ====
@@ -3771,5 +3771,15 @@ $count, 1,"should have matched once only [RT#36046]");
iseq(
}
+{
+ use warnings;
+ local $Message = "ASCII pattern that really is utf8";
+ my @w;
+ local $SIG{__WA...