We were finally able to narrow this bug down to a small test case.  I
have also attached a patch that fixes it.


#!/usr/bin/perl -Tw
$SIG{'__WARN__'} = sub {warn $_[0]};
my $tainted = substr($ENV{'PATH'}, 0, 0);
my $pat = "Testing %s\n" . $tainted;
"foo" =~ m/(.*)/;
my $foo = $1;
my $s = sprintf($pat, undef);  # << corrupts $1!!
"bar" =~ m/(.$tainted*)/;
my $bar = $1;
my $test = 'print "OK\n"' . $tainted;
$test =~ m/(.*)/;
$test = $1;   # try to untaint
eval($test);


Output:
Use of uninitialized value in sprintf at - line 7.
Insecure dependency in eval while running with -T switch at - line 13.


In a nutshell, the bug was caused by having a single line that taints
and then calls a warning handler.  After that, $1 becomes increasing
corrupted. (Insert Devel::Peek::Dump($1) at various points to see this.)

Brendan, is there anything else you need from us to get this into
unstable?  Will you push this upstream, or should I write to p5p myself?

Chris Heath
AutoWeb Communications, Inc.
--- mg.c.bad	2005-10-04 11:29:10.000000000 -0400
+++ mg.c	2005-10-04 11:39:01.000000000 -0400
@@ -768,7 +768,10 @@
 
 	      getrx:
 		if (i >= 0) {
+		    int oldtainted = PL_tainted;
+		    TAINT_NOT;
 		    sv_setpvn(sv, s, i);
+		    PL_tainted = oldtainted;
 		    if (RX_MATCH_UTF8(rx) && is_utf8_string((U8*)s, i))
 			SvUTF8_on(sv);
 		    else

Reply via email to