Forbid using tainted formats in printf and sprintf
Rafael Garcia-Suarez [Tue, 7 Nov 2006 14:23:08 +0000 (14:23 +0000)]
p4raw-id: //depot/perl@29225

pod/perl595delta.pod
pp.c
pp_sys.c
t/op/taint.t

index a7e3b40..98044d8 100644 (file)
@@ -11,6 +11,11 @@ between 5.8.0 and 5.9.4.
 
 =head1 Incompatible Changes
 
+=head2 Tainting and printf
+
+When perl is run under taint mode, C<printf()> and C<sprintf()> will now
+reject any tainted format argument.
+
 =head2 Removal of the bytecode compiler and of perlcc
 
 C<perlcc>, the byteloader and the supporting modules (B::C, B::CC,
diff --git a/pp.c b/pp.c
index 43e400b..a9ca236 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3310,6 +3310,8 @@ PP(pp_index)
 PP(pp_sprintf)
 {
     dVAR; dSP; dMARK; dORIGMARK; dTARGET;
+    if (SvTAINTED(MARK[1]))
+       TAINT_PROPER("sprintf");
     do_sprintf(TARG, SP-MARK, MARK+1);
     TAINT_IF(SvTAINTED(TARG));
     SP = ORIGMARK;
index e71eecd..1d0b552 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1485,6 +1485,8 @@ PP(pp_prtf)
        goto just_say_no;
     }
     else {
+       if (SvTAINTED(MARK[1]))
+           TAINT_PROPER("printf");
        do_sprintf(sv, SP - MARK, MARK + 1);
        if (!do_print(sv, fp))
            goto just_say_no;
index 8311690..be9071f 100755 (executable)
@@ -17,7 +17,7 @@ use Config;
 use File::Spec::Functions;
 
 BEGIN { require './test.pl'; }
-plan tests => 251;
+plan tests => 255;
 
 $| = 1;
 
@@ -1204,3 +1204,14 @@ SKIP:
     $o->untainted;
 }
 
+{
+    # tests for tainted format in s?printf
+    eval { printf($TAINT . "# %s\n", "foo") };
+    like($@, qr/^Insecure dependency in printf/, q/printf doesn't like tainted formats/);
+    eval { printf("# %s\n", $TAINT . "foo") };
+    ok(!$@, q/printf accepts other tainted args/);
+    eval { sprintf($TAINT . "# %s\n", "foo") };
+    like($@, qr/^Insecure dependency in sprintf/, q/sprintf doesn't like tainted formats/);
+    eval { sprintf("# %s\n", $TAINT . "foo") };
+    ok(!$@, q/sprintf accepts other tainted args/);
+}