This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
don't taint $DB::sub
authorDavid Mitchell <davem@iabyn.com>
Wed, 25 Aug 2010 11:15:41 +0000 (12:15 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 25 Aug 2010 11:15:41 +0000 (12:15 +0100)
[perl #76872] showed a case where code like the following, run under -d,
would cause $DB::sub to get set:

    $tainted_expression && func()

The tainted expression sets PL_tainted, so calling func() under -d, which
sets $DB::sub, causes it to get tainted.

Consequently any further sub calls would set PL_tainted while getting the
old value of $DB::sub (and cause the new value to be tainted too), and if
the sub was XS, then its code would be executed with PL_tainted set.
It isn't an issue with perl subs as the first nextstate op resets
PL_tainted.

MANIFEST
lib/perl5db.t
lib/perl5db/t/taint [new file with mode: 0644]
util.c

index 9b14309..3ab86a5 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -3603,6 +3603,7 @@ lib/perl5db/t/proxy-constants     Tests for the Perl debugger
 lib/perl5db/t/rt-61222         Tests for the Perl debugger
 lib/perl5db/t/rt-66110         Tests for the Perl debugger
 lib/perl5db/t/symbol-table-bug Tests for the Perl debugger
+lib/perl5db/t/taint            Tests for the Perl debugger
 lib/PerlIO.pm                  PerlIO support module
 lib/Pod/Functions.pm           used by pod/splitpod
 lib/Pod/Html.pm                        Convert POD data to HTML
index 3f68759..b2f7266 100644 (file)
@@ -27,7 +27,7 @@ my $dev_tty = '/dev/tty';
     }
 }
 
-plan(8);
+plan(9);
 
 sub rc {
     open RC, ">", ".perldb" or die $!;
@@ -167,6 +167,15 @@ SKIP: {
     like($output, "All tests successful.", "[perl #66110]");
 }
 
+# taint tests
+
+{
+    local $ENV{PERLDB_OPTS} = "ReadLine=0 NonStop=1";
+    my $output = runperl(switches => [ '-d', '-T' ], stderr => 1,
+                       progfile => '../lib/perl5db/t/taint');
+    is($output, '[$^X][done]', "taint");
+}
+
 
 # clean up.
 
diff --git a/lib/perl5db/t/taint b/lib/perl5db/t/taint
new file mode 100644 (file)
index 0000000..e40f194
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/perl -T
+#
+# This code is used by lib/perl5db.t !!!
+#
+use Scalar::Util qw(tainted);
+
+# [perl #76872] don't taint $DB::sub
+
+sub f {}
+
+BEGIN {
+    print "[\$^X]" if tainted($^X);
+    ($^X || 1)  && f(); # maybe taint $DB::sub;
+    print "[\$DB::sub]" if tainted($DB::sub);
+}
+print "[done]";
+
diff --git a/util.c b/util.c
index 9e1e2c8..1809f70 100644 (file)
--- a/util.c
+++ b/util.c
@@ -6489,12 +6489,15 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv)
 {
     dVAR;
     SV * const dbsv = GvSVn(PL_DBsub);
+    const bool save_taint = PL_tainted;
+
     /* We do not care about using sv to call CV;
      * it's for informational purposes only.
      */
 
     PERL_ARGS_ASSERT_GET_DB_SUB;
 
+    PL_tainted = FALSE;
     save_item(dbsv);
     if (!PERLDB_SUB_NN) {
        GV * const gv = CvGV(cv);
@@ -6521,6 +6524,7 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv)
        (void)SvIOK_on(dbsv);
        SvIV_set(dbsv, PTR2IV(cv));     /* Do it the quickest way  */
     }
+    TAINT_IF(save_taint);
 }
 
 int