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