Taint shmread().
Jarkko Hietaniemi [Sun, 19 Mar 2000 01:48:47 +0000 (01:48 +0000)]
p4raw-id: //depot/cfgperl@5811

doio.c
pod/perldelta.pod
pod/perlfunc.pod
pod/perlsec.pod
t/op/taint.t

diff --git a/doio.c b/doio.c
index e22902f..0247cb9 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -1994,6 +1994,10 @@ Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
        SvCUR_set(mstr, msize);
        *SvEND(mstr) = '\0';
        SvSETMAGIC(mstr);
+#ifndef INCOMPLETE_TAINTS
+       /* who knows who has been playing with this shared memory? */
+       SvTAINTED_on(mstr);
+#endif
     }
     else {
        I32 n;
index 88655be..52a6fba 100644 (file)
@@ -212,6 +212,12 @@ Because the user can affect her own encrypted password and login shell
 the password and shell returned by the getpwent(), getpwnam(), and
 getpwuid() functions are tainted.
 
+=head2 The shmread() now taints its variable
+
+Because other (untrusted) processes can modify shared memory segments
+for their own nefarious purposes, the variable modified by shmread()
+becomes tainted.
+
 =back
 
 =head2 C Source Incompatibilities
index c4c7e3f..cc84d73 100644 (file)
@@ -4022,8 +4022,8 @@ detaching from it.  When reading, VAR must be a variable that will
 hold the data read.  When writing, if STRING is too long, only SIZE
 bytes are used; if STRING is too short, nulls are written to fill out
 SIZE bytes.  Return true if successful, or false if there is an error.
-See also C<IPC::SysV> documentation and the C<IPC::Shareable> module
-from CPAN.
+shmread() taints the variable. See also C<IPC::SysV> documentation and
+the C<IPC::Shareable> module from CPAN.
 
 =item shutdown SOCKET,HOW
 
index 713a89c..b271f70 100644 (file)
@@ -32,18 +32,18 @@ program more secure than the corresponding C program.
 You may not use data derived from outside your program to affect
 something else outside your program--at least, not by accident.  All
 command line arguments, environment variables, locale information (see
-L<perllocale>), results of certain system calls (readdir, readlink,
-the password, gcos and shell fields of the getpw* calls), and all file
-input are marked as "tainted".  Tainted data may not be used directly
-or indirectly in any command that invokes a sub-shell, nor in any
-command that modifies files, directories, or processes. (B<Important
-exception>: If you pass a list of arguments to either C<system> or
-C<exec>, the elements of that list are B<NOT> checked for
-taintedness.) Any variable set to a value derived from tainted data
-will itself be tainted, even if it is logically impossible for the
-tainted data to alter the variable.  Because taintedness is associated
-with each scalar value, some elements of an array can be tainted and
-others not.
+L<perllocale>), results of certain system calls (readdir(),
+readlink(), the variable of() shmread, the password, gcos and shell
+fields of the getpwxxx() calls), and all file input are marked as
+"tainted".  Tainted data may not be used directly or indirectly in any
+command that invokes a sub-shell, nor in any command that modifies
+files, directories, or processes. (B<Important exception>: If you pass
+a list of arguments to either C<system> or C<exec>, the elements of
+that list are B<NOT> checked for taintedness.) Any variable set to a
+value derived from tainted data will itself be tainted, even if it is
+logically impossible for the tainted data to alter the variable.
+Because taintedness is associated with each scalar value, some
+elements of an array can be tainted and others not.
 
 For example:
 
index 883f069..51dcbd8 100755 (executable)
@@ -94,7 +94,7 @@ print PROG 'print "@ARGV\n"', "\n";
 close PROG;
 my $echo = "$Invoke_Perl $ECHO";
 
-print "1..149\n";
+print "1..150\n";
 
 # First, let's make sure that Perl is checking the dangerous
 # environment variables. Maybe they aren't set yet, so we'll
@@ -605,3 +605,36 @@ else {
     $why =~ s/e/'-'.$$/ge;
     test 149,     tainted $why;
 }
+
+# test shmread
+{
+    if ($Config{d_shm}) {
+       use IPC::SysV qw(IPC_PRIVATE IPC_RMID S_IRWXU S_IRWXG S_IRWXO);
+
+       my $sent = "foobar";
+       my $rcvd;
+       my $size = 2000;
+       my $key = shmget(IPC_PRIVATE, $size, S_IRWXU|S_IRWXG|S_IRWXO) ||
+           warn "# shmget failed: $!\n";
+       if ($key >= 0) {
+           if (shmwrite($key, $sent, 0, 60)) {
+               if (shmread($key, $rcvd, 0, 60)) {
+                   substr($rcvd, index($rcvd, "\0")) = '';
+               } else {
+                   warn "# shmread failed: $!\n";
+               }
+           } else {
+               warn "# shmwrite failed: $!\n";
+           }
+           shmctl($key, IPC_RMID, 0) || warn "# shmctl failed: $!\n";
+       }
+
+       if ($rcvd eq $sent) {
+           test 150, tainted $rcvd;
+       } else {
+           print "ok 150 # Skipped: SysV shared memory operation failed\n";
+       }
+    } else {
+       for (150) { print "ok $_ # Skipped: SysV shared memory is not available\n"; }
+    }
+}