On Sat, Mar 16, 2002 at 12:27:27PM +0100, Andreas J. Koenig wrote:
> >>>>> On 02 Mar 2002 18:41:15 -0800, Stephen Zander <[EMAIL PROTECTED]> said:
> 
>   > If someone would like to send them to me, I'll get my act together a
>   > little better and get a new release out.
> 
> A pseudo-patch would be OK? I found that Tar.pm contains
> 
>         chdir $_;
> 
> and
> 
>     chdir $cwd
>         if @path;
> 
> I'd like to see these guarded by something like:
> 
>    ... or Carp::croak("Could not chdir to directory ...: $!");
> 
> That would be a very high security requirement.

<Bones>Its worse than that, Jim.</Bones>

There currently *is* a bug in Archive::Tar about this very thing.
When unpacking DBI-1.20 I believe it was, it spewed bits of itself all
over my home directory.  Why my home directory you may ask?

Because...

    chdir;      # Means goto $HOME

the above is documented, but...

    chdir '';   # also means goto $HOME
    chdir undef # this, too

these have recently been deprecated and warnings added, but that won't
be showing up unless you're using 5.7.3.


So the proper way to guard a chdir is:

    sub my_chdir {
        my($dir) = shift;

        if( defined $dir && length $dir ) {
            return chdir $dir || croak "Could not chdir to $dir";
        }
        else {
            croak "chdir given an undefined or empty directory";
        }
    }

and here's a patch.


--- Tar.pm.old  Thu Apr 27 18:50:15 2000
+++ Tar.pm      Sat Mar 16 12:57:51 2002
@@ -1,7 +1,7 @@
 package Archive::Tar;
 
 use strict;
-use Carp qw(carp);
+use Carp qw(carp croak);
 use Cwd;
 use Fcntl qw(O_RDONLY O_RDWR O_WRONLY O_CREAT O_TRUNC F_DUPFD F_GETFL);
 use File::Basename;
@@ -83,6 +83,17 @@
     return;
 }
 
+sub _safe_chdir {
+    my($dir) = shift;
+
+    if( defined $dir && length $dir ) {
+        return chdir $dir || croak "Could not chdir to $dir";
+    }
+    else {
+        croak "chdir given an undefined or empty directory";
+    }
+}
+
 sub error {
     $error;
 }
@@ -584,7 +595,7 @@
            next;
        }
        mkdir $_, 0777 unless -d _;
-       chdir $_;
+       _safe_chdir $_;
     }
 
     if ($entry->{type} == FILE) {      # Ordinary file
@@ -636,7 +647,7 @@
     # chmod is done last, in case it makes file readonly
     # (this accomodates DOSish OSes)
     chmod $entry->{mode}, $file;
-    chdir $cwd
+    _safe_chdir $cwd
        if @path;
 }
 


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>    http://www.pobox.com/~schwern/
Perl Quality Assurance      <[EMAIL PROTECTED]>         Kwalitee Is Job One
It's Flypaper Licking time!

Reply via email to