[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

rpms/perl/FC-3 perl-5.8.5-CAN-2005-0448.patch, NONE, 1.1 perl.spec, 1.48, 1.49



Author: prockai

Update of /cvs/dist/rpms/perl/FC-3
In directory cvs.devel.redhat.com:/tmp/cvs-serv25875

Modified Files:
	perl.spec 
Added Files:
	perl-5.8.5-CAN-2005-0448.patch 
Log Message:
* Thu Jun 16 2005 Petr Rockai <prockai redhat com> - 3:5.8.5-13.FC3
- fix for CAN-2005-0448 - patch by Brendan O'Dea from Debian, backported
  by myself



perl-5.8.5-CAN-2005-0448.patch:
 Path.pm |  243 +++++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 127 insertions(+), 116 deletions(-)

--- NEW FILE perl-5.8.5-CAN-2005-0448.patch ---
--- perl-5.8.5/lib/File/Path.pm.CAN-2005-0448	2005-06-16 13:46:31.713141936 +0200
+++ perl-5.8.5/lib/File/Path.pm	2005-06-16 13:54:10.978323016 +0200
@@ -64,11 +64,11 @@
 
 =item *
 
-a boolean value, which if TRUE will cause C<rmtree> to
-print a message each time it examines a file, giving the
-name of the file, and indicating whether it's using C<rmdir>
-or C<unlink> to remove it, or that it's skipping it.
-(defaults to FALSE)
+a boolean value, which if FALSE (the default for non-root users) will
+cause C<rmtree> to adjust the mode of directories (if required) prior
+to attempting to remove the contents.  Note that on interruption or
+failure of C<rmtree>, directories may be left with more permissive
+modes for the owner.
 
 =item *
 
@@ -84,15 +84,6 @@
 It returns the number of files successfully deleted.  Symlinks are
 simply deleted and not followed.
 
-B<NOTE:> If the third parameter is not TRUE, C<rmtree> is B<unsecure>
-in the face of failure or interruption.  Files and directories which
-were not deleted may be left with permissions reset to allow world
-read and write access.  Note also that the occurrence of errors in
-rmtree can be determined I<only> by trapping diagnostic messages
-using C<$SIG{__WARN__}>; it is not apparent from the return value.
-Therefore, you must be extremely careful about using C<rmtree($foo,$bar,0)>
-in situations where security is an issue.
-
 =head1 DIAGNOSTICS
 
 =over 4
@@ -118,6 +109,7 @@
 use Exporter ();
 use strict;
 use warnings;
+use Cwd 'getcwd';
 
 our $VERSION = "1.06";
 our @ISA = qw( Exporter );
@@ -166,111 +158,130 @@
     @created;
 }
 
-sub rmtree {
-    my($roots, $verbose, $safe) = @_;
-    my(@files);
-    my($count) = 0;
-    $verbose ||= 0;
-    $safe ||= 0;
-
-    if ( defined($roots) && length($roots) ) {
-      $roots = [$roots] unless ref $roots;
-    }
-    else {
-      carp "No root path(s) specified\n";
-      return 0;
-    }
-
-    my($root);
-    foreach $root (@{$roots}) {
-    	if ($Is_MacOS) {
-	    $root = ":$root" if $root !~ /:/;
-	    $root =~ s#([^:])\z#$1:#;
-	} else {
-	    $root =~ s#/\z##;
+sub _rmtree;
+sub _rmtree
+{
+    my ($path, $prefix, $up, $up_dev, $up_ino, $verbose, $safe) = @_;
+
+    my ($dev, $ino) = lstat $path or return 0;
+    unless (-d _)
+    {
+	print "unlink $prefix$path\n" if $verbose;
+	unless (unlink $path)
+	{
+	    carp "Can't remove file $prefix$path ($!)";
+	    return 0;
 	}
-	(undef, undef, my $rp) = lstat $root or next;
-	$rp &= 07777;	# don't forget setuid, setgid, sticky bits
-	if ( -d _ ) {
-	    # notabene: 0777 is for making readable in the first place,
-	    # it's also intended to change it to writable in case we have
-	    # to recurse in which case we are better than rm -rf for 
-	    # subtrees with strange permissions
-	    chmod(0700, ($Is_VMS ? VMS::Filespec::fileify($root) : $root))
-	      or carp "Can't make directory $root read+writeable: $!"
-		unless $safe;
-
-	    if (opendir my $d, $root) {
-		no strict 'refs';
-		if (!defined ${"\cTAINT"} or ${"\cTAINT"}) {
-		    # Blindly untaint dir names
-		    @files = map { /^(.*)$/s ; $1 } readdir $d;
-		} else {
-		    @files = readdir $d;
-		}
-		closedir $d;
-	    }
-	    else {
-	        carp "Can't read $root: $!";
-		@files = ();
-	    }
 
-	    # Deleting large numbers of files from VMS Files-11 filesystems
-	    # is faster if done in reverse ASCIIbetical order 
-	    @files = reverse @files if $Is_VMS;
-	    ($root = VMS::Filespec::unixify($root)) =~ s#\.dir\z## if $Is_VMS;
-	    if ($Is_MacOS) {
-		@files = map("$root$_", @files);
-	    } else {
-		@files = map("$root/$_", grep $_!~/^\.{1,2}\z/s,@files);
-	    }
-	    $count += rmtree(\ files,$verbose,$safe);
-	    if ($safe &&
-		($Is_VMS ? !&VMS::Filespec::candelete($root) : !-w $root)) {
-		print "skipped $root\n" if $verbose;
-		next;
-	    }
-	    chmod 0700, $root
-	      or carp "Can't make directory $root writeable: $!"
-		if $force_writeable;
-	    print "rmdir $root\n" if $verbose;
-	    if (rmdir $root) {
-		++$count;
-	    }
-	    else {
-		carp "Can't remove directory $root: $!";
-		chmod($rp, ($Is_VMS ? VMS::Filespec::fileify($root) : $root))
-		    or carp("and can't restore permissions to "
-		            . sprintf("0%o",$rp) . "\n");
-	    }
-	}
-	else { 
-	    if ($safe &&
-		($Is_VMS ? !&VMS::Filespec::candelete($root)
-		         : !(-l $root || -w $root)))
-	    {
-		print "skipped $root\n" if $verbose;
-		next;
-	    }
-	    chmod 0600, $root
-	      or carp "Can't make file $root writeable: $!"
-		if $force_writeable;
-	    print "unlink $root\n" if $verbose;
-	    # delete all versions under VMS
-	    for (;;) {
-		unless (unlink $root) {
-		    carp "Can't unlink file $root: $!";
-		    if ($force_writeable) {
-			chmod $rp, $root
-			    or carp("and can't restore permissions to "
-			            . sprintf("0%o",$rp) . "\n");
-		    }
-		    last;
-		}
-		++$count;
-		last unless $Is_VMS && lstat $root;
-	    }
+	return 1;
+    }
+
+    unless (chdir $path)
+    {
+	carp "Can't chdir to $prefix$path ($!)";
+	return 0;
+    }
+
+    # avoid a race condition where a directory may be replaced by a
+    # symlink between the lstat and the chdir
+    my ($new_dev, $new_ino, $perm) = stat '.';
+    unless ("$new_dev:$new_ino" eq "$dev:$ino")
+    {
+	croak "Directory $prefix$path changed before chdir, aborting";
+    }
+
+    $perm &= 07777;
+    my $nperm = $perm | 0700;
+    unless ($safe or $nperm == $perm or chmod $nperm, '.')
+    {
+	carp "Can't make directory $prefix$path read+writeable ($!)";
+	$nperm = $perm;
+    }
+
+    my $count = 0;
+    if (opendir my $dir, '.')
+    {
+	my $entry;
+	while (defined ($entry = readdir $dir))
+	{
+	    next if $entry =~ /^\.\.?$/;
+	    $entry =~ /^(.*)$/s; $entry = $1; # untaint
+	    $count += _rmtree $entry, "$prefix$path/", '..', $dev, $ino,
+		$verbose, $safe;
 	}
+
+	closedir $dir;
+    }
+
+    # restore directory permissions if required (in case the rmdir
+    # below fails) now, while we're still in the directory and may do
+    # so without a race via '.'
+    unless ($nperm == $perm or chmod $perm, '.')
+    {
+	carp "Can't restore permissions on directory $prefix$path ($!)";
+    }
+
+    # don't leave the caller in an unexpected directory
+    unless (chdir $up)
+    {
+	croak "Can't return to $up from $prefix$path ($!)";
+    }
+
+    # ensure that a chdir ..  didn't take us somewhere other than
+    # where we expected (see CVE-2002-0435)
+    unless (($new_dev, $new_ino) = stat '.'
+	and "$new_dev:$new_ino" eq "$up_dev:$up_ino")
+    {
+	croak "Previous directory $up changed since entering $prefix$path";
+    }
+
+    print "rmdir $prefix$path\n" if $verbose;
+    if (rmdir $path)
+    {
+	$count++;
+    }
+    else
+    {
+	carp "Can't remove directory $prefix$path ($!)";
+    }
+
+    return $count;
+}
+
+sub rmtree
+{
+    my ($p, $verbose, $safe) = @_;
+    $p = [] unless defined $p and length $p;
+    $p = [ $p ] unless ref $p;
+    my @paths = grep defined && length, @$p;
+
+    # default to "unsafe" for non-root (will chmod dirs)
+    $safe = $> ? 0 : 1 unless defined $safe;
+
+    unless (@paths)
+    {
+	carp "No root path(s) specified";
+	return;
+    }
+
+    my $oldpwd = &Cwd::getcwd;
+    $oldpwd or do {
+	carp "Can't fetch initial working directory";
+	return;
+    };
+
+    my ($dev, $ino) = stat '.' or do {
+	carp "Can't stat initial working directory";
+	return;
+    };
+
+    # untaint
+    for ($oldpwd) { /^(.*)$/s; $_ = $1 }
+
+    my $count = 0;
+    for my $path (@paths)
+    {
+	$count += _rmtree $path, '', $oldpwd, $dev, $ino, $verbose, $safe;
     }
 
     $count;


Index: perl.spec
===================================================================
RCS file: /cvs/dist/rpms/perl/FC-3/perl.spec,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- perl.spec	28 Apr 2005 23:35:21 -0000	1.48
+++ perl.spec	16 Jun 2005 12:13:26 -0000	1.49
@@ -5,7 +5,7 @@
 %define multilib_64_archs x86_64 s390x ppc64 sparc64
 
 %define perlver 5.8.5
-%define perlrel 12.FC3
+%define perlrel 13.FC3
 %define perlepoch 3
 
 Provides: perl(:WITH_PERLIO)
@@ -102,6 +102,7 @@
 
 # CAN-2004-0452 fix
 Patch26: perl-5.8.0-rmtree.patch
+Patch27: perl-5.8.5-CAN-2005-0448.patch
 
 # arch-specific patches
 Patch100: perl-5.8.1-fpic.patch
@@ -217,6 +218,7 @@
 %patch24 -p1
 %patch25 -p0
 %patch26 -p1
+%patch27 -p1 -b .CAN-2005-0448
 
 %patch100 -p1
 
@@ -415,6 +417,10 @@
 %endif
 
 %changelog
+* Thu Jun 16 2005 Petr Rockai <prockai redhat com> - 3:5.8.5-13.FC3
+- fix for CAN-2005-0448 - patch by Brendan O'Dea from Debian, backported
+  by myself
+
 * Thu Apr 28 2005 Ville Skyttä <ville.skytta at iki.fi> - 3:5.8.5-12.FC3
 - Apply fix for CAN-2004-0452 (#156128, #146774).
 - Drop incorrect provides from the main package and release tag munging


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]