Subject: | Support for --no-same-permissions style behavior |
The CPAN module recently switched to using Archive::Tar by default for
extracting module tarballs and to prevent security problems like
globally writable files, setuid and setgid, they're using the
$Archive::Tar::CHMOD=0 setting. Unfortunately CHMOD=0 has the
side-effect of stripping the executable bit from all extracted files and
in some circumstances increasing permissions beyond what is specified in
the archive.
https://rt.cpan.org/Ticket/Display.html?id=46384
Archive::Tar could really use the equivalent of GNU tar's
--no-same-permissions flag (remove setid bits and apply umask.)
The attached patch adds a new setting to provide this type of behavior.
Subject: | same_permissions.diff |
diff -Nur Archive-Tar-1.48.orig/lib/Archive/Tar.pm Archive-Tar-1.48/lib/Archive/Tar.pm
--- Archive-Tar-1.48.orig/lib/Archive/Tar.pm 2009-04-20 12:02:04.000000000 -0500
+++ Archive-Tar-1.48/lib/Archive/Tar.pm 2009-05-28 18:27:44.000000000 -0500
@@ -22,7 +22,7 @@
use strict;
use vars qw[$DEBUG $error $VERSION $WARN $FOLLOW_SYMLINK $CHOWN $CHMOD
- $DO_NOT_USE_PREFIX $HAS_PERLIO $HAS_IO_STRING
+ $DO_NOT_USE_PREFIX $HAS_PERLIO $HAS_IO_STRING $SAME_PERMISSIONS
$INSECURE_EXTRACT_MODE @ISA @EXPORT
];
@@ -34,6 +34,7 @@
$VERSION = "1.48";
$CHOWN = 1;
$CHMOD = 1;
+$SAME_PERMISSIONS = $> == 0 ? 1 : 0;
$DO_NOT_USE_PREFIX = 0;
$INSECURE_EXTRACT_MODE = 0;
@@ -806,7 +807,11 @@
### only chmod if we're allowed to, but never chmod symlinks, since they'll
### change the perms on the file they're linking too...
if( $CHMOD and not -l $full ) {
- chmod $entry->mode, $full or
+ my $mode = $entry->mode;
+ unless ($SAME_PERMISSIONS) {
+ $mode &= ~(oct(7000) | umask);
+ }
+ chmod $mode, $full or
$self->_error( qq[Could not chown '$full' to ] . $entry->mode );
}
@@ -1761,6 +1766,15 @@
The default is C<1>.
+=head2 $Archive::Tar::SAME_PERMISSIONS
+
+When, C<$Archive::Tar::CHMOD> is enabled, this setting controls whether
+the permissions on files from the archive are used without modification
+of if they are filtered by removing any setid bits and applying the
+current umask.
+
+The default is C<1> for the root user and C<0> for normal users.
+
=head2 $Archive::Tar::DO_NOT_USE_PREFIX
By default, C<Archive::Tar> will try to put paths that are over