public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] repo/gentoo:master commit in: dev-perl/Archive-Zip/files/, dev-perl/Archive-Zip/
@ 2018-09-23  6:04 Kent Fredric
  0 siblings, 0 replies; only message in thread
From: Kent Fredric @ 2018-09-23  6:04 UTC (permalink / raw
  To: gentoo-commits

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 18508 bytes --]

commit:     0188c36db1324b3b47a4020bb61ce7c61c629d9d
Author:     Kent Fredric <kentnl <AT> gentoo <DOT> org>
AuthorDate: Sun Sep 23 05:58:06 2018 +0000
Commit:     Kent Fredric <kentnl <AT> gentoo <DOT> org>
CommitDate: Sun Sep 23 06:03:35 2018 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=0188c36d

dev-perl/Archive-Zip: Cleanup 1.600.0-r1 re bug #666398

This version is now obsoleted by a newer version which has the fix
applied by upstream in an official capacity anyway, so keeping around
this sec-fix is mostly just wasted effort now.

Closes: https://bugs.gentoo.org/666398
Package-Manager: Portage-2.3.49, Repoman-2.3.10

 dev-perl/Archive-Zip/Archive-Zip-1.600.0-r1.ebuild |  35 --
 .../files/Archive-Zip-1.60-CVE-2018-10860.patch    | 395 ---------------------
 2 files changed, 430 deletions(-)

diff --git a/dev-perl/Archive-Zip/Archive-Zip-1.600.0-r1.ebuild b/dev-perl/Archive-Zip/Archive-Zip-1.600.0-r1.ebuild
deleted file mode 100644
index 2b727f01eb3..00000000000
--- a/dev-perl/Archive-Zip/Archive-Zip-1.600.0-r1.ebuild
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 1999-2018 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-EAPI=6
-
-DIST_AUTHOR=PHRED
-DIST_VERSION=1.60
-DIST_EXAMPLES=("examples/*")
-inherit perl-module
-
-DESCRIPTION="A wrapper that lets you read Zip archive members as if they were files"
-
-SLOT="0"
-KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~ppc ~ppc64 ~sparc ~x86 ~x86-fbsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~sparc-solaris ~x64-solaris ~x86-solaris"
-IUSE="test"
-
-RDEPEND="
-	>=virtual/perl-Compress-Raw-Zlib-2.17.0
-	virtual/perl-File-Path
-	>=virtual/perl-File-Spec-0.800.0
-	virtual/perl-File-Temp
-	virtual/perl-IO
-	virtual/perl-Time-Local
-"
-DEPEND="${RDEPEND}
-	virtual/perl-ExtUtils-MakeMaker
-	test? (
-		dev-perl/Test-MockModule
-		>=virtual/perl-Test-Simple-0.880.0
-	)
-"
-
-PATCHES=(
-	"${FILESDIR}/${PN}-1.60-CVE-2018-10860.patch"
-)

diff --git a/dev-perl/Archive-Zip/files/Archive-Zip-1.60-CVE-2018-10860.patch b/dev-perl/Archive-Zip/files/Archive-Zip-1.60-CVE-2018-10860.patch
deleted file mode 100644
index 94ade1abdfb..00000000000
--- a/dev-perl/Archive-Zip/files/Archive-Zip-1.60-CVE-2018-10860.patch
+++ /dev/null
@@ -1,395 +0,0 @@
-From 4c200ada6595c0add0de2c450cc44cebd1dbb609 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
-Date: Fri, 15 Jun 2018 14:49:47 +0200
-Subject: Prevent from traversing symlinks and parent directories when
- extracting
-
-If an attacker-supplied archive contains symbolic links and files that
-referes to the symbolic links in their path components, the user can
-be tricked into overwriting any arbitrary file.
-
-The same issue is with archives whose members refer to a parent
-directory (..) in their path components.
-
-This patch fixes it by aborting an extraction (extractTree(),
-extractMember(), extractMemberWithoutPaths()) in those cases by not
-traversing the dangerous paths and returning AZ_ERORR instead.
-
-However, if a user supplies a local file name, the security checks are
-not performed. This is based on the assumption that a user knows
-what's on his local file system.
-
-CVE-2018-10860
-Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1591449
-Bug: https://bugs.gentoo.org/660466
-Bug: https://github.com/redhotpenguin/perl-Archive-Zip/pull/33
----
- MANIFEST                               |   3 +
- lib/Archive/Zip.pm                     |   8 ++
- lib/Archive/Zip/Archive.pm             |  37 +++++
- t/25_traversal.t                       | 189 +++++++++++++++++++++++++
- t/data/dotdot-from-unexistant-path.zip | Bin 0 -> 245 bytes
- t/data/link-dir.zip                    | Bin 0 -> 260 bytes
- t/data/link-samename.zip               | Bin 0 -> 257 bytes
- 7 files changed, 237 insertions(+)
- create mode 100644 t/25_traversal.t
- create mode 100644 t/data/dotdot-from-unexistant-path.zip
- create mode 100644 t/data/link-dir.zip
- create mode 100644 t/data/link-samename.zip
-
-diff --git a/MANIFEST b/MANIFEST
-index 37d8b8d..dd9675a 100644
---- a/MANIFEST
-+++ b/MANIFEST
-@@ -59,6 +59,7 @@ t/21_zip64.t
- t/22_deflated_dir.t
- t/23_closed_handle.t
- t/24_unicode_win32.t
-+t/25_traversal.t
- t/badjpeg/expected.jpg
- t/badjpeg/source.zip
- t/common.pm
-@@ -68,6 +69,7 @@ t/data/crypcomp.zip
- t/data/crypt.zip
- t/data/def.zip
- t/data/defstr.zip
-+t/data/dotdot-from-unexistant-path.zip
- t/data/empty.zip
- t/data/emptydef.zip
- t/data/emptydefstr.zip
-@@ -75,6 +77,7 @@ t/data/emptystore.zip
- t/data/emptystorestr.zip
- t/data/good_github11.zip
- t/data/jar.zip
-+t/data/link-dir.zip
- t/data/linux.zip
- t/data/mkzip.pl
- t/data/perl.zip
-diff --git a/lib/Archive/Zip.pm b/lib/Archive/Zip.pm
-index ca82e31..907808b 100644
---- a/lib/Archive/Zip.pm
-+++ b/lib/Archive/Zip.pm
-@@ -1145,6 +1145,9 @@ member is used as the name of the extracted file or
- directory.
- If you pass C<$extractedName>, it should be in the local file
- system's format.
-+If you do not pass C<$extractedName> and the internal filename traverses
-+a parent directory or a symbolic link, the extraction will be aborted with
-+C<AC_ERROR> for security reason.
- All necessary directories will be created. Returns C<AZ_OK>
- on success.
- 
-@@ -1162,6 +1165,9 @@ extracted member (its paths will be deleted too). Otherwise,
- the internal filename of the member (minus paths) is used as
- the name of the extracted file or directory. Returns C<AZ_OK>
- on success.
-+If you do not pass C<$extractedName> and the internal filename is equalled
-+to a local symbolic link, the extraction will be aborted with C<AC_ERROR> for
-+security reason.
- 
- =item addMember( $member )
- 
-@@ -1609,6 +1615,8 @@ a/x to f:\d\e\x
- 
- a/b/c to f:\d\e\b\c and ignore ax/d/e and d/e
- 
-+If the path to the extracted file traverses a parent directory or a symbolic
-+link, the extraction will be aborted with C<AC_ERROR> for security reason.
- Returns an error code or AZ_OK if everything worked OK.
- 
- =back
-diff --git a/lib/Archive/Zip/Archive.pm b/lib/Archive/Zip/Archive.pm
-index 48f0d1a..b0d3e46 100644
---- a/lib/Archive/Zip/Archive.pm
-+++ b/lib/Archive/Zip/Archive.pm
-@@ -185,6 +185,8 @@ sub extractMember {
-         $dirName = File::Spec->catpath($volumeName, $dirName, '');
-     } else {
-         $name = $member->fileName();
-+        if ((my $ret = _extractionNameIsSafe($name))
-+            != AZ_OK) { return $ret; }
-         ($dirName = $name) =~ s{[^/]*$}{};
-         $dirName = Archive::Zip::_asLocalName($dirName);
-         $name    = Archive::Zip::_asLocalName($name);
-@@ -218,6 +220,8 @@ sub extractMemberWithoutPaths {
-     unless ($name) {
-         $name = $member->fileName();
-         $name =~ s{.*/}{};    # strip off directories, if any
-+        if ((my $ret = _extractionNameIsSafe($name))
-+            != AZ_OK) { return $ret; }
-         $name = Archive::Zip::_asLocalName($name);
-     }
-     my $rc = $member->extractToFileNamed($name, @_);
-@@ -827,6 +831,37 @@ sub addTreeMatching {
-     return $self->addTree($root, $dest, $matcher, $compressionLevel);
- }
- 
-+# Check if one of the components of a path to the file or the file name
-+# itself is an already existing symbolic link. If yes then return an
-+# error. Continuing and writing to a file traversing a link posseses
-+# a security threat, especially if the link was extracted from an
-+# attacker-supplied archive. This would allow writing to an arbitrary
-+# file. The same applies when using ".." to escape from a working
-+# directory. <https://bugzilla.redhat.com/show_bug.cgi?id=1591449>
-+sub _extractionNameIsSafe {
-+    my $name = shift;
-+    my ($volume, $directories) = File::Spec->splitpath($name, 1);
-+    my @directories = File::Spec->splitdir($directories);
-+    if (grep '..' eq $_, @directories) {
-+        return _error(
-+            "Could not extract $name safely: a parent directory is used");
-+    }
-+    my @path;
-+    my $path;
-+    for my $directory (@directories) {
-+        push @path, $directory;
-+        $path = File::Spec->catpath($volume, File::Spec->catdir(@path), '');
-+        if (-l $path) {
-+            return _error(
-+                "Could not extract $name safely: $path is an existing symbolic link");
-+        }
-+        if (!-e $path) {
-+            last;
-+        }
-+    }
-+    return AZ_OK;
-+}
-+
- # $zip->extractTree( $root, $dest [, $volume] );
- #
- # $root and $dest are Unix-style.
-@@ -861,6 +896,8 @@ sub extractTree {
-         $fileName =~ s{$pattern}{$dest};       # in Unix format
-                                                # convert to platform format:
-         $fileName = Archive::Zip::_asLocalName($fileName, $volume);
-+        if ((my $ret = _extractionNameIsSafe($fileName))
-+            != AZ_OK) { return $ret; }
-         my $status = $member->extractToFileNamed($fileName);
-         return $status if $status != AZ_OK;
-     }
-diff --git a/t/25_traversal.t b/t/25_traversal.t
-new file mode 100644
-index 0000000..d03dede
---- /dev/null
-+++ b/t/25_traversal.t
-@@ -0,0 +1,189 @@
-+use strict;
-+use warnings;
-+
-+use Archive::Zip qw( :ERROR_CODES );
-+use File::Spec;
-+use File::Path;
-+use lib 't';
-+use common;
-+
-+use Test::More tests => 41;
-+
-+# These tests check for CVE-2018-10860 vulnerabilities.
-+# If an archive contains a symlink and then a file that traverses that symlink,
-+# extracting the archive tree could write into an abitrary file selected by
-+# the symlink value.
-+# Another issue is if an archive contains a file whose path component refers
-+# to a parent direcotory. Then extracting that file could write into a file
-+# out of current working directory subtree.
-+# These tests check extracting of these files is refuses and that they are
-+# indeed not created.
-+
-+# Suppress croaking errors, the tests produce some.
-+Archive::Zip::setErrorHandler(sub {});
-+my ($existed, $ret, $zip, $allowed_file, $forbidden_file);
-+
-+# Change working directory to a temporary directory because some tested
-+# functions operarates there and we need prepared symlinks there.
-+my @data_path = (File::Spec->splitdir(File::Spec->rel2abs('.')), 't', 'data');
-+ok(chdir TESTDIR, "Working directory changed");
-+
-+# Case 1:
-+#   link-dir -> /tmp
-+#   link-dir/gotcha-linkdir
-+# writes into /tmp/gotcha-linkdir file.
-+SKIP: {
-+    # Symlink tests make sense only if a file system supports them.
-+    my $link = 'trylink';
-+    $ret = eval { symlink('.', $link)};
-+    skip 'Symbolic links are not supported', 12 if $@;
-+    unlink $link;
-+
-+    # Extracting an archive tree must fail
-+    $zip = Archive::Zip->new();
-+    isa_ok($zip, 'Archive::Zip');
-+    is($zip->read(File::Spec->catfile(@data_path, 'link-dir.zip')), AZ_OK,
-+        'Archive read');
-+    $existed = -e File::Spec->catfile('', 'tmp', 'gotcha-linkdir');
-+    $ret = eval { $zip->extractTree() };
-+    is($ret, AZ_ERROR, 'Tree extraction aborted');
-+    SKIP: {
-+        skip 'A canary file existed before the test', 1 if $existed;
-+        ok(! -e File::Spec->catfile('link-dir', 'gotcha-linkdir'),
-+            'A file was not created in a symlinked directory');
-+    }
-+    ok(unlink(File::Spec->catfile('link-dir')), 'link-dir removed');
-+
-+    # The same applies to extracting an archive member without an explicit
-+    # local file name. It must abort.
-+    $link = 'link-dir';
-+    ok(symlink('.', $link), 'A symlink to a directory created');
-+    $forbidden_file = File::Spec->catfile($link, 'gotcha-linkdir');
-+    $existed = -e $forbidden_file;
-+    $ret = eval { $zip->extractMember('link-dir/gotcha-linkdir') };
-+    is($ret, AZ_ERROR, 'Member extraction without a local name aborted');
-+    SKIP: {
-+        skip 'A canary file existed before the test', 1 if $existed;
-+        ok(! -e $forbidden_file,
-+            'A file was not created in a symlinked directory');
-+    }
-+
-+    # But allow extracting an archive member into a supplied file name
-+    $allowed_file = File::Spec->catfile($link, 'file');
-+    $ret = eval { $zip->extractMember('link-dir/gotcha-linkdir', $allowed_file) };
-+    is($ret, AZ_OK, 'Member extraction passed');
-+    ok(-e $allowed_file, 'File created');
-+    ok(unlink($allowed_file), 'File removed');
-+    ok(unlink($link), 'A symlink to a directory removed');
-+}
-+
-+# Case 2:
-+#   unexisting/../../../../../tmp/gotcha-dotdot-unexistingpath
-+# writes into ../../../../tmp/gotcha-dotdot-unexistingpath, that is
-+# /tmp/gotcha-dotdot-unexistingpath file if CWD is not deeper than
-+# 4 directories.
-+$zip = Archive::Zip->new();
-+isa_ok($zip, 'Archive::Zip');
-+is($zip->read(File::Spec->catfile(@data_path,
-+            'dotdot-from-unexistant-path.zip')), AZ_OK, 'Archive read');
-+$forbidden_file = File::Spec->catfile('..', '..', '..', '..', 'tmp',
-+    'gotcha-dotdot-unexistingpath');
-+$existed = -e $forbidden_file;
-+$ret = eval { $zip->extractTree() };
-+is($ret, AZ_ERROR, 'Tree extraction aborted');
-+SKIP: {
-+    skip 'A canary file existed before the test', 1 if $existed;
-+    ok(! -e $forbidden_file, 'A file was not created in a parent directory');
-+}
-+
-+# The same applies to extracting an archive member without an explicit local
-+# file name. It must abort.
-+$existed = -e $forbidden_file;
-+$ret = eval { $zip->extractMember(
-+        'unexisting/../../../../../tmp/gotcha-dotdot-unexistingpath',
-+    ) };
-+is($ret, AZ_ERROR, 'Member extraction without a local name aborted');
-+SKIP: {
-+    skip 'A canary file existed before the test', 1 if $existed;
-+    ok(! -e $forbidden_file, 'A file was not created in a parent directory');
-+}
-+
-+# But allow extracting an archive member into a supplied file name
-+ok(mkdir('directory'), 'Directory created');
-+$allowed_file = File::Spec->catfile('directory', '..', 'file');
-+$ret = eval { $zip->extractMember(
-+        'unexisting/../../../../../tmp/gotcha-dotdot-unexistingpath',
-+        $allowed_file
-+    ) };
-+is($ret, AZ_OK, 'Member extraction passed');
-+ok(-e $allowed_file, 'File created');
-+ok(unlink($allowed_file), 'File removed');
-+
-+# Case 3:
-+#   link-file -> /tmp/gotcha-samename
-+#   link-file
-+# writes into /tmp/gotcha-samename. It must abort. (Or replace the symlink in
-+# more relaxed mode in the future.)
-+$zip = Archive::Zip->new();
-+isa_ok($zip, 'Archive::Zip');
-+is($zip->read(File::Spec->catfile(@data_path, 'link-samename.zip')), AZ_OK,
-+    'Archive read');
-+$existed = -e File::Spec->catfile('', 'tmp', 'gotcha-samename');
-+$ret = eval { $zip->extractTree() };
-+is($ret, AZ_ERROR, 'Tree extraction aborted');
-+SKIP: {
-+    skip 'A canary file existed before the test', 1 if $existed;
-+    ok(! -e File::Spec->catfile('', 'tmp', 'gotcha-samename'),
-+        'A file was not created through a symlinked file');
-+}
-+ok(unlink(File::Spec->catfile('link-file')), 'link-file removed');
-+
-+# The same applies to extracting an archive member using extractMember()
-+# without an explicit local file name. It must abort.
-+my $link = 'link-file';
-+my $target = 'target';
-+ok(symlink($target, $link), 'A symlink to a file created');
-+$forbidden_file = File::Spec->catfile($target);
-+$existed = -e $forbidden_file;
-+# Select a member by order due to same file names.
-+my $member = ${[$zip->members]}[1];
-+ok($member, 'A member to extract selected');
-+$ret = eval { $zip->extractMember($member) };
-+is($ret, AZ_ERROR,
-+    'Member extraction using extractMember() without a local name aborted');
-+SKIP: {
-+    skip 'A canary file existed before the test', 1 if $existed;
-+    ok(! -e $forbidden_file,
-+        'A symlinked target file was not created');
-+}
-+
-+# But allow extracting an archive member using extractMember() into a supplied
-+# file name.
-+$allowed_file = $target;
-+$ret = eval { $zip->extractMember($member, $allowed_file) };
-+is($ret, AZ_OK, 'Member extraction using extractMember() passed');
-+ok(-e $allowed_file, 'File created');
-+ok(unlink($allowed_file), 'File removed');
-+
-+# The same applies to extracting an archive member using
-+# extractMemberWithoutPaths() without an explicit local file name.
-+# It must abort.
-+$existed = -e $forbidden_file;
-+# Select a member by order due to same file names.
-+$ret = eval { $zip->extractMemberWithoutPaths($member) };
-+is($ret, AZ_ERROR,
-+    'Member extraction using extractMemberWithoutPaths() without a local name aborted');
-+SKIP: {
-+    skip 'A canary file existed before the test', 1 if $existed;
-+    ok(! -e $forbidden_file,
-+        'A symlinked target file was not created');
-+}
-+
-+# But allow extracting an archive member using extractMemberWithoutPaths()
-+# into a supplied file name.
-+$allowed_file = $target;
-+$ret = eval { $zip->extractMemberWithoutPaths($member, $allowed_file) };
-+is($ret, AZ_OK, 'Member extraction using extractMemberWithoutPaths() passed');
-+ok(-e $allowed_file, 'File created');
-+ok(unlink($allowed_file), 'File removed');
-+ok(unlink($link), 'A symlink to a file removed');
-diff --git a/t/data/dotdot-from-unexistant-path.zip b/t/data/dotdot-from-unexistant-path.zip
-new file mode 100644
-index 0000000..faaa5bb
---- /dev/null
-+++ b/t/data/dotdot-from-unexistant-path.zip
-@@ -0,0 +1 @@
-+PK\x03\x04\x14\0\0\0\0\0ÐNÔL½D\x1d\x1f\0\0\0\x1f\0\0\0:\0\0\0unexisting/../../../../../tmp/gotcha-dotdot-unexistingpathgotcha: .. with unexisting pathPK\x01\x02\x14\x03\x14\0\0\0\0\0ÐNÔL½D\x1d\x1f\0\0\0\x1f\0\0\0:\0\0\0\0\0\0\0\0\0\0\0¶\0\0\0\0unexisting/../../../../../tmp/gotcha-dotdot-unexistingpathPK\x05\x06\0\0\0\0\x01\0\x01\0h\0\0\0w\0\0\0\0\0
-\ No newline at end of file
-diff --git a/t/data/link-dir.zip b/t/data/link-dir.zip
-new file mode 100644
-index 0000000..99fbb43
---- /dev/null
-+++ b/t/data/link-dir.zip
-@@ -0,0 +1,4 @@
-+PK\x03\x04\x14\0\0\0\0\0·YÒL.Ä»
-+\x04\0\0\0\x04\0\0\0\b\0\0\0link-dir/tmpPK\x03\x04\x14\0\0\0\0\0·YÒLWõ.Š\x14\0\0\0\x14\0\0\0\x17\0\0\0link-dir/gotcha-linkdirgotcha via dir link
-+PK\x01\x02\x14\x03\x14\0\0\0\0\0·YÒL.Ä»
-+\x04\0\0\0\x04\0\0\0\b\0\0\0\0\0\0\0\0\0\0\0ÿ¡\0\0\0\0link-dirPK\x01\x02\x14\x03\x14\0\0\0\0\0·YÒLWõ.Š\x14\0\0\0\x14\0\0\0\x17\0\0\0\0\0\0\0\0\0\0\0¶*\0\0\0link-dir/gotcha-linkdirPK\x05\x06\0\0\0\0\x02\0\x02\0{\0\0\0s\0\0\0\0\0
-\ No newline at end of file
-diff --git a/t/data/link-samename.zip b/t/data/link-samename.zip
-new file mode 100644
-index 0000000..e9036c0
---- /dev/null
-+++ b/t/data/link-samename.zip
-@@ -0,0 +1,2 @@
-+PK\x03\x04\x14\0\0\0\0\0\x17YÒLvò«\x05\x14\0\0\0\x14\0\0\0	\0\0\0link-file/tmp/gotcha-samenamePK\x03\x04\x14\0\0\0\0\0\x17YÒLÈkŒÉ^[\0\0\0^[\0\0\0	\0\0\0link-filegotcha via same-named link
-+PK\x01\x02\x14\x03\x14\0\0\0\0\0\x17YÒLvò«\x05\x14\0\0\0\x14\0\0\0	\0\0\0\0\0\0\0\0\0\0\0ÿ¡\0\0\0\0link-filePK\x01\x02\x14\x03\x14\0\0\0\0\0\x17YÒLÈkŒÉ^[\0\0\0^[\0\0\0	\0\0\0\0\0\0\0\0\0\0\0¶;\0\0\0link-filePK\x05\x06\0\0\0\0\x02\0\x02\0n\0\0\0}\0\0\0\0\0
-\ No newline at end of file
--- 
-2.17.1
-


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-09-23  6:04 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-23  6:04 [gentoo-commits] repo/gentoo:master commit in: dev-perl/Archive-Zip/files/, dev-perl/Archive-Zip/ Kent Fredric

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox