debian/0000775000000000000000000000000013426546103007174 5ustar debian/rules0000775000000000000000000000114312253051164010246 0ustar #!/usr/bin/make -f .PHONY: build %: dh $@ --parallel --with autoreconf build: dh $@ --parallel --with autoreconf override_dh_auto_configure: dh_auto_configure -- --without-openssl --with-nettle \ --enable-bsdtar=shared --enable-bsdcpio=shared override_dh_auto_test: ifneq (,$(shell locale -a | grep en_US.utf8)) _VERBOSITY_LEVEL=1 dh_auto_test --parallel else mkdir -p tmp-locales localedef -i /usr/share/i18n/locales/en_US -c -f UTF-8 \ -A /usr/share/locale/locale.alias tmp-locales/en_US.UTF-8 _VERBOSITY_LEVEL=1 LOCPATH=$(CURDIR)/tmp-locales dh_auto_test --parallel rm -rf tmp-locales endif debian/source/0000775000000000000000000000000012150214725010467 5ustar debian/source/lintian-overrides0000664000000000000000000000021212150214725014043 0ustar # Ignore this, since currently only debhelper (>= 8.1.3~) is needed. libarchive source: package-needs-versioned-debhelper-build-depends 9 debian/source/format0000664000000000000000000000001412150214725011675 0ustar 3.0 (quilt) debian/watch0000664000000000000000000000023012150214725010213 0ustar version=3 opts=dversionmangle=s/[-.+~]?(cvs|svn|git|snapshot|pre|hg|repack)(.*)$//i,pasv \ http://www.libarchive.org/downloads/libarchive-(.*)\.tar\.gz debian/libarchive-dev.docs0000664000000000000000000000001412150214725012720 0ustar NEWS README debian/libarchive-dev.install0000664000000000000000000000010512150214725013437 0ustar usr/include usr/lib/*/lib*.a usr/lib/*/lib*.so usr/lib/*/pkgconfig/* debian/bsdcpio.install0000664000000000000000000000002012150214725012172 0ustar usr/bin/bsdcpio debian/control0000664000000000000000000001222612253050705010575 0ustar Source: libarchive Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Debian Libarchive Maintainers Uploaders: Andreas Henriksson , Andres Mejia Build-Depends: debhelper (>= 8.1.3~), dh-autoreconf, libbz2-dev, liblzma-dev, libxml2-dev, zlib1g-dev, libacl1-dev [!hurd-any], e2fslibs-dev, libattr1-dev, sharutils, nettle-dev, liblzo2-dev, locales | locales-all Standards-Version: 3.9.4 Section: libs Homepage: http://www.libarchive.org/ Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/libarchive.git Vcs-Git: git://anonscm.debian.org/collab-maint/libarchive.git XS-Testsuite: autopkgtest Package: libarchive-dev Section: libdevel Architecture: any Multi-Arch: same Depends: libarchive13 (= ${binary:Version}), ${misc:Depends} Replaces: libarchive1 (<< 2.8.5-3) Breaks: libarchive1 (<< 2.8.5-3) Description: Multi-format archive and compression library (development files) The libarchive library provides a flexible interface for reading and writing archives in various formats such as tar and cpio. libarchive also supports reading and writing archives compressed using various compression filters such as gzip and bzip2. The library is inherently stream-oriented; readers serially iterate through the archive, writers serially add things to the archive. . Archive formats supported are: . * tar (read and write, including GNU extensions) * pax (read and write, including GNU and star extensions) * cpio (read and write, including odc and newc variants) * iso9660 (read and write, including Joliet and Rockridge extensions, with some limitations) * zip (read only, with some limitations, uses zlib) * mtree (read and write) * shar (write only) * ar (read and write, including BSD and GNU/SysV variants) * empty (read only; in particular, note that no other format will accept an empty file) * raw (read only) * xar (read only) * rar (read only, with some limitations) * 7zip (read and write, with some limitations) . Filters supported are: . * gzip (read and write, uses zlib) * bzip2 (read and write, uses bzlib) * compress (read and write, uses an internal implementation) * uudecode (read only) * separate command-line compressors with fixed-signature auto-detection * xz and lzma (read and write using liblzma) . This package provides the files necessary for development with libarchive. Package: libarchive13 Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: lrzip Description: Multi-format archive and compression library (shared library) The libarchive library provides a flexible interface for reading and writing archives in various formats such as tar and cpio. libarchive also supports reading and writing archives compressed using various compression filters such as gzip and bzip2. The library is inherently stream-oriented; readers serially iterate through the archive, writers serially add things to the archive. . Archive formats supported are: . * tar (read and write, including GNU extensions) * pax (read and write, including GNU and star extensions) * cpio (read and write, including odc and newc variants) * iso9660 (read and write, including Joliet and Rockridge extensions, with some limitations) * zip (read only, with some limitations, uses zlib) * mtree (read and write) * shar (write only) * ar (read and write, including BSD and GNU/SysV variants) * empty (read only; in particular, note that no other format will accept an empty file) * raw (read only) * xar (read only) * rar (read only, with some limitations) * 7zip (read and write, with some limitations) . Filters supported are: . * gzip (read and write, uses zlib) * bzip2 (read and write, uses bzlib) * compress (read and write, uses an internal implementation) * uudecode (read only) * separate command-line compressors with fixed-signature auto-detection * xz and lzma (read and write using liblzma) . This package provides the libarchive shared library. Package: bsdtar Architecture: any Depends: libarchive13 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Section: utils Suggests: bsdcpio Description: Implementation of the 'tar' program from FreeBSD The bsdtar program is the default system 'tar' program used on FreeBSD. bsdtar uses the libarchive library as a backend which does all of the work for reading and writing archives in various formats. Package: bsdcpio Architecture: any Depends: libarchive13 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Section: utils Suggests: bsdtar Description: Implementation of the 'cpio' program from FreeBSD The bsdcpio program is the default system 'cpio' program used on FreeBSD. bsdcpio uses the libarchive library as a backend which does all of the work for reading and writing archives in various formats. debian/libarchive13.lintian-overrides0000664000000000000000000000017412150214725015025 0ustar # See 418637 for the history of this bug and the override libarchive1 binary: package-name-doesnt-match-sonames libarchive2 debian/README.Debian0000664000000000000000000000057312150214725011235 0ustar As libarchive requires large-file support enabled under i386 on Linux you must add the following to any of your own source files: #define _FILE_OFFSET_BITS 64 Applications compiled under i386 on Linux without this options will produce empty archives and corrupt output from archives when reading them. -- John Goerzen , Thu, 5 Jun 2008 15:36:22 -0500 debian/copyright0000664000000000000000000001310312150214725011120 0ustar This package was originally debianized by John Goerzen on Mon, 10 Oct 2005 19:24:56 -0500. The debian package maintenance was handed over to Andreas Henrikson in February 2010. It was downloaded from http://code.google.com/p/libarchive/ old versions from http://people.freebsd.org/~kientzle/libarchive/ Copyright Holders: Copyright (c) 2003-2011 Tim Kientzle Copyright (c) 2008-2011 Michihiro NAKAJIMA Copyright (c) 2011 libarchive Project Copyright (c) 2011 Andres Mejia Copyright (c) 2007-2010 Joerg Sonnenberger Copyright (c) 2009 Andreas Henriksson Copyright (c) 2008 Anselm Strauss Copyright (c) 2008 Miklos Vajna Copyright (c) 2008 Jaakko Heinonen Copyright (c) 2003-2007 Kees Zeelenberg Copyright (c) 2007 Kai Wang Copyright (c) 2006 Rudolf Marek SYSGO s.r.o. Copyright (c) 2002 Thomas Moestl Portions Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies) Portions Copyright (c) 2001 The NetBSD Foundation, Inc Portions Copyright (c) 1996-2008 PostgreSQL Global Development Group Portions Copyright (c) 1985, 1986, 1992, 1993 The Regents of the University of California License: * Copyright (c) 2003-2011 Tim Kientzle * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Portions with copyright to The Regents of the University of California have the following license. * Copyright (c) 1985, 1986, 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Diomidis Spinellis and James A. Woods, derived from original * work by Spencer Thomas and Joseph Orost. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. Portions with copyright to PostgreSQL Global Development Group have the following license. * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without a written agreement * is hereby granted, provided that the above copyright notice and this * paragraph and the following two paragraphs appear in all copies. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. The PPMdH codec code is in the Public Domain. The code has the following disclaimer. * 2010-03-12 : Igor Pavlov : Public domain * This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain debian/bsdcpio.manpages0000664000000000000000000000005012150214725012322 0ustar debian/tmp/usr/share/man/man1/bsdcpio.1 debian/libarchive13.install0000664000000000000000000000002412150214725013027 0ustar usr/lib/*/lib*.so.* debian/tests/0000775000000000000000000000000012252111672010331 5ustar debian/tests/control0000664000000000000000000000011212150214725011726 0ustar Tests: minitar Depends: build-essential, file, libarchive-dev, pkg-config debian/tests/minitar0000664000000000000000000000302412252111672011716 0ustar #!/bin/sh set -e # autopkgtest check: Build and run the example minitar program against # libarchive, to verify that the headers and pkg-config file are installed # correctly and minitar works as expected. # Author: Benjamin Drung gcc -O2 -g -Wno-unused-result -o minitar examples/minitar/minitar.c $(pkg-config --cflags --libs libarchive) # Create different tarballs echo "Deadbeaf" > foo echo "Compressing foo.tar..." ./minitar -cf foo.tar foo echo "Compressing foo.tar.gz..." ./minitar -czf foo.tar.gz foo echo "Compressing foo.tar.bz2..." ./minitar -cyf foo.tar.bz2 foo # Test tarballs for correct mime type echo "Testing mime type of foo.tar..." test "$(file -b --mime-type foo.tar)" = "application/x-tar" echo "Testing mime type of foo.tar.gz..." test "$(file -b --mime-type foo.tar.gz)" = "application/gzip" echo "Testing mime type of foo.tar.bz2..." test "$(file -b --mime-type foo.tar.bz2)" = "application/x-bzip2" # FIXME: Extracting with minitar crashes; using untar instead. gcc -O2 -g -Wno-unused-result -o untar examples/untar.c $(pkg-config --cflags --libs libarchive) # Extract tarballs and compare content mv foo foo.orig echo "Extracting foo.tar..." # FIXME ./minitar -xf foo.tar ./untar -xf foo.tar cmp foo foo.orig rm foo foo.tar echo "Extracting foo.tar.gz..." # FIXME ./minitar -xf foo.tar.gz tar -xf foo.tar.gz cmp foo foo.orig rm foo foo.tar.gz echo "Extracting foo.tar.bz2..." # FIXME ./minitar -xf foo.tar.bz2 tar -xf foo.tar.bz2 cmp foo foo.orig rm foo foo.tar.bz2 # Clean-up rm foo.orig minitar untar debian/bsdtar.docs0000664000000000000000000000001412150214725011313 0ustar NEWS README debian/libarchive-dev.manpages0000664000000000000000000000010012150214725013557 0ustar debian/tmp/usr/share/man/man3/* debian/tmp/usr/share/man/man5/* debian/compat0000664000000000000000000000000212150214725010365 0ustar 9 debian/gbp.conf0000664000000000000000000000003612150214725010605 0ustar [DEFAULT] pristine-tar = True debian/bsdtar.manpages0000664000000000000000000000004712150214725012164 0ustar debian/tmp/usr/share/man/man1/bsdtar.1 debian/bsdcpio.docs0000664000000000000000000000001412150214725011457 0ustar NEWS README debian/patches/0000775000000000000000000000000013426546103010623 5ustar debian/patches/CVE-2015-8916.patch0000664000000000000000000000216712741434300013253 0ustar From b2e2abbb13ddcd962470cc1adb43b085f6e407a4 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Fri, 6 Feb 2015 22:45:58 -0800 Subject: [PATCH] Issues 396, 397: Ignore entries with empty filenames. Bugs in the rar and cab readers lead to returning entries with empty filenames. Make bsdtar resistant to this. Of course, we should also fix the rar and cab readers to handle these cases correctly and either return correctly-populated entries or fail cleanly. --- tar/read.c | 6 ++++++ 1 file changed, 6 insertions(+) Index: libarchive-3.1.2/tar/read.c =================================================================== --- libarchive-3.1.2.orig/tar/read.c 2016-07-13 08:49:02.138132561 -0400 +++ libarchive-3.1.2/tar/read.c 2016-07-13 08:49:02.134132512 -0400 @@ -247,6 +247,12 @@ } if (r == ARCHIVE_FATAL) break; + const char *p = archive_entry_pathname(entry); + if (p == NULL || p[0] == '\0') { + lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping."); + bsdtar->return_value = 1; + continue; + } if (bsdtar->uid >= 0) { archive_entry_set_uid(entry, bsdtar->uid); debian/patches/CVE-2019-1000019.patch0000664000000000000000000000541413426544602013470 0ustar From 65a23f5dbee4497064e9bb467f81138a62b0dae1 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Tue, 1 Jan 2019 16:01:40 +1100 Subject: [PATCH] 7zip: fix crash when parsing certain archives Fuzzing with CRCs disabled revealed that a call to get_uncompressed_data() would sometimes fail to return at least 'minimum' bytes. This can cause the crc32() invocation in header_bytes to read off into invalid memory. A specially crafted archive can use this to cause a crash. An ASAN trace is below, but ASAN is not required - an uninstrumented binary will also crash. ==7719==ERROR: AddressSanitizer: SEGV on unknown address 0x631000040000 (pc 0x7fbdb3b3ec1d bp 0x7ffe77a51310 sp 0x7ffe77a51150 T0) ==7719==The signal is caused by a READ memory access. #0 0x7fbdb3b3ec1c in crc32_z (/lib/x86_64-linux-gnu/libz.so.1+0x2c1c) #1 0x84f5eb in header_bytes (/tmp/libarchive/bsdtar+0x84f5eb) #2 0x856156 in read_Header (/tmp/libarchive/bsdtar+0x856156) #3 0x84e134 in slurp_central_directory (/tmp/libarchive/bsdtar+0x84e134) #4 0x849690 in archive_read_format_7zip_read_header (/tmp/libarchive/bsdtar+0x849690) #5 0x5713b7 in _archive_read_next_header2 (/tmp/libarchive/bsdtar+0x5713b7) #6 0x570e63 in _archive_read_next_header (/tmp/libarchive/bsdtar+0x570e63) #7 0x6f08bd in archive_read_next_header (/tmp/libarchive/bsdtar+0x6f08bd) #8 0x52373f in read_archive (/tmp/libarchive/bsdtar+0x52373f) #9 0x5257be in tar_mode_x (/tmp/libarchive/bsdtar+0x5257be) #10 0x51daeb in main (/tmp/libarchive/bsdtar+0x51daeb) #11 0x7fbdb27cab96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310 #12 0x41dd09 in _start (/tmp/libarchive/bsdtar+0x41dd09) This was primarly done with afl and FairFuzz. Some early corpus entries may have been generated by qsym. --- libarchive/archive_read_support_format_7zip.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c +++ libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c @@ -2886,13 +2886,7 @@ get_uncompressed_data(struct archive_rea if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) { /* Copy mode. */ - /* - * Note: '1' here is a performance optimization. - * Recall that the decompression layer returns a count of - * available bytes; asking for more than that forces the - * decompressor to combine reads by copying data. - */ - *buff = __archive_read_ahead(a, 1, &bytes_avail); + *buff = __archive_read_ahead(a, minimum, &bytes_avail); if (bytes_avail <= 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, debian/patches/CVE-2016-5418-1.patch0000664000000000000000000000417013060275135013404 0ustar From 1fa9c7bf90f0862036a99896b0501c381584451a Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 21 Aug 2016 17:11:45 -0700 Subject: [PATCH] Issue #744 (part of Issue #743): Enforce sandbox with very long pathnames Because check_symlinks is handled separately from the deep-directory support, very long pathnames cause problems. Previously, the code ignored most failures to lstat() a path component. In particular, this led to check_symlinks always passing for very long paths, which in turn provides a way to evade the symlink checks in the sandboxing code. We now fail on unrecognized lstat() failures, which plugs this hole at the cost of disabling deep directory support when the user requests sandboxing. TODO: This probably cannot be completely fixed without entirely reimplementing the deep directory support to integrate the symlink checks. I want to reimplement the deep directory hanlding someday anyway; openat() and related system calls now provide a much cleaner way to handle deep directories than the chdir approach used by this code. --- libarchive/archive_write_disk_posix.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) Index: libarchive-3.1.2/libarchive/archive_write_disk_posix.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_write_disk_posix.c 2017-03-09 10:52:59.317794207 -0500 +++ libarchive-3.1.2/libarchive/archive_write_disk_posix.c 2017-03-09 10:52:59.317794207 -0500 @@ -2379,8 +2379,18 @@ r = lstat(a->name, &st); if (r != 0) { /* We've hit a dir that doesn't exist; stop now. */ - if (errno == ENOENT) + if (errno == ENOENT) { break; + } else { + /* Note: This effectively disables deep directory + * support when security checks are enabled. + * Otherwise, very long pathnames that trigger + * an error here could evade the sandbox. + * TODO: We could do better, but it would probably + * require merging the symlink checks with the + * deep-directory editing. */ + return (ARCHIVE_FAILED); + } } else if (S_ISLNK(st.st_mode)) { if (c == '\0') { /* debian/patches/CVE-2016-8689.patch0000664000000000000000000000431513060276141013262 0ustar From 7f17c791dcfd8c0416e2cd2485b19410e47ef126 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 18 Sep 2016 18:14:58 -0700 Subject: [PATCH] Issue 761: Heap overflow reading corrupted 7Zip files The sample file that demonstrated this had multiple 'EmptyStream' attributes. The first one ended up being used to calculate certain statistics, then was overwritten by the second which was incompatible with those statistics. The fix here is to reject any header with multiple EmptyStream attributes. While here, also reject headers with multiple EmptyFile, AntiFile, Name, or Attributes markers. --- libarchive/archive_read_support_format_7zip.c | 10 ++++++++++ 1 file changed, 10 insertions(+) Index: libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c 2017-03-09 11:01:34.315279989 -0500 +++ libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c 2017-03-09 11:01:34.311279946 -0500 @@ -2337,6 +2337,8 @@ switch (type) { case kEmptyStream: + if (h->emptyStreamBools != NULL) + return (-1); h->emptyStreamBools = calloc((size_t)zip->numFiles, sizeof(*h->emptyStreamBools)); if (h->emptyStreamBools == NULL) @@ -2357,6 +2359,8 @@ return (-1); break; } + if (h->emptyFileBools != NULL) + return (-1); h->emptyFileBools = calloc(empty_streams, sizeof(*h->emptyFileBools)); if (h->emptyFileBools == NULL) @@ -2371,6 +2375,8 @@ return (-1); break; } + if (h->antiBools != NULL) + return (-1); h->antiBools = calloc(empty_streams, sizeof(*h->antiBools)); if (h->antiBools == NULL) @@ -2397,6 +2403,8 @@ if ((ll & 1) || ll < zip->numFiles * 4) return (-1); + if (zip->entry_names != NULL) + return (-1); zip->entry_names = malloc(ll); if (zip->entry_names == NULL) return (-1); @@ -2449,6 +2457,8 @@ if ((p = header_bytes(a, 2)) == NULL) return (-1); allAreDefined = *p; + if (h->attrBools != NULL) + return (-1); h->attrBools = calloc((size_t)zip->numFiles, sizeof(*h->attrBools)); if (h->attrBools == NULL) debian/patches/series0000664000000000000000000000223113426544615012044 0ustar examples.patch examples-offset-type.patch mtree-filename-length-fix.patch fix-lzo-test-case.patch Initialize-buff-to-all-zeros.patch Allow-the-option-to-use-no-2nd-stage-compression-wit.patch Fix-test_archive_write_add_filter_by_name_lrzip-test.patch fix-CVE-2013-0211.patch CVE-2015-2304.patch CVE-2016-1541.patch issue502.patch CVE-2015-8916.patch CVE-2015-8919.patch CVE-2015-8920.patch CVE-2015-8921.patch CVE-2015-8922.patch CVE-2015-8923.patch CVE-2015-8924.patch CVE-2015-8925.patch CVE-2015-8926.patch CVE-2015-8928.patch CVE-2015-8930.patch CVE-2015-8931.patch CVE-2015-8932.patch CVE-2015-8933.patch CVE-2015-8934.patch CVE-2016-4300.patch CVE-2016-4302.patch CVE-2016-4809.patch CVE-2016-5844.patch CVE-2016-5418-1.patch CVE-2016-5418-2.patch CVE-2016-5418-3.patch CVE-2016-5418-4.patch CVE-2016-5418-5.patch CVE-2016-6250.patch CVE-2016-7166.patch CVE-2016-8687.patch CVE-2016-8688.patch CVE-2016-8689.patch CVE-2017-5601.patch CVE-2016-10209.patch CVE-2016-10349-and-CVE-2016-10350.patch CVE-2017-14166.patch CVE-2017-14501.patch CVE-2017-14503.patch CVE-2017-14502.patch CVE-2018-1000877.patch CVE-2018-1000878.patch CVE-2019-1000019.patch CVE-2019-1000020.patch debian/patches/CVE-2015-8933.patch0000664000000000000000000000203412741436750013256 0ustar Backport of: From 3c7a6dc6694d9b26400d2bd672e04d09ed8a4276 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 26 Jul 2015 17:09:22 -0700 Subject: [PATCH] Issue #582: reject sparse blocks with negative size or offset, detect overflow when tracking sparse blocks --- libarchive/archive_read_support_format_tar.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_tar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_tar.c 2016-07-13 09:06:29.630619916 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_tar.c 2016-07-13 09:06:29.626619869 -0400 @@ -2075,6 +2075,10 @@ else tar->sparse_list = p; tar->sparse_last = p; + if (remaining < 0 || offset < 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data"); + return (ARCHIVE_FATAL); + } p->offset = offset; p->remaining = remaining; return (ARCHIVE_OK); debian/patches/CVE-2015-8928.patch0000664000000000000000000000624312741457270013270 0ustar Backport of: From 64d56286ccc5d26d1eec1ef835e8e671f3ba6b84 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 3 Apr 2016 11:03:22 -0700 Subject: [PATCH] Issue 550: Fix out-of-bounds read in mtree. The mtree parser scanned from the end of the string to identify the filename when the filename is the last element of the line. If the filename was the entire line, the logic would scan back to before the start of the string. The revised logic scans from the beginning of the string and remembers the last separator position to locate the trailing filename. --- libarchive/archive_read_support_format_mtree.c | 51 ++++++++++++++------------ 1 file changed, 28 insertions(+), 23 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_mtree.c 2016-07-13 11:28:36.988227884 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c 2016-07-13 11:30:35.093774032 -0400 @@ -826,8 +826,8 @@ struct mtree_entry *entry; struct mtree_option *iter; const char *next, *eq, *name, *end; - size_t len; - int r; + size_t name_len, len; + int r, i; if ((entry = malloc(sizeof(*entry))) == NULL) { archive_set_error(&a->archive, errno, "Can't allocate memory"); @@ -847,43 +847,48 @@ *last_entry = entry; if (is_form_d) { - /* - * This form places the file name as last parameter. - */ - name = line + line_len -1; + /* Filename is last item on line. */ + /* Adjust line_len to trim trailing whitespace */ while (line_len > 0) { - if (*name != '\r' && *name != '\n' && - *name != '\t' && *name != ' ') + char last_character = line[line_len - 1]; + if (last_character == '\r' + || last_character == '\n' + || last_character == '\t' + || last_character == ' ') { + line_len--; + } else { break; - name--; - line_len--; + } } - len = 0; - while (line_len > 0) { - if (*name == '\r' || *name == '\n' || - *name == '\t' || *name == ' ') { - name++; - break; + /* Name starts after the last whitespace separator */ + name = line; + for (i = 0; i < line_len; i++) { + if (line[i] == '\r' + || line[i] == '\n' + || line[i] == '\t' + || line[i] == ' ') { + name = line + i + 1; } - name--; - line_len--; - len++; } + name_len = line + line_len - name; end = name; } else { - len = strcspn(line, " \t\r\n"); + /* Filename is first item on line */ + name_len = strcspn(line, " \t\r\n"); name = line; - line += len; + line += name_len; end = line + line_len; } + /* name/name_len is the name within the line. */ + /* line..end brackets the entire line except the name */ - if ((entry->name = malloc(len + 1)) == NULL) { + if ((entry->name = malloc(name_len + 1)) == NULL) { archive_set_error(&a->archive, errno, "Can't allocate memory"); return (ARCHIVE_FATAL); } - memcpy(entry->name, name, len); - entry->name[len] = '\0'; + memcpy(entry->name, name, name_len); + entry->name[name_len] = '\0'; parse_escapes(entry->name, entry); for (iter = *global; iter != NULL; iter = iter->next) { debian/patches/CVE-2015-8919.patch0000664000000000000000000000246212741434310013255 0ustar From e8a2e4d2e6b450a239bb8f9d74239fa434bf7d35 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 7 Feb 2015 13:32:58 -0800 Subject: [PATCH] Issue 402: Failed to recognize empty dir name in lha/lzh file When parsing a directory name, we checked for the name length being zero, but not for the first byte being a null byte. Add a similar check for the file case. --- libarchive/archive_read_support_format_lha.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_lha.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_lha.c 2016-07-13 08:49:10.186229510 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_lha.c 2016-07-13 08:49:10.186229510 -0400 @@ -1230,13 +1230,15 @@ archive_string_empty(&lha->filename); break; } + if (extdheader[0] == '\0') + goto invalid; archive_strncpy(&lha->filename, (const char *)extdheader, datasize); break; case EXT_DIRECTORY: - if (datasize == 0) + if (datasize == 0 || extdheader[0] == '\0') /* no directory name data. exit this case. */ - break; + goto invalid; archive_strncpy(&lha->dirname, (const char *)extdheader, datasize); debian/patches/issue502.patch0000664000000000000000000000445412715357702013237 0ustar Description: fix denial of service via malformed cpio archive Origin: upstream, https://github.com/libarchive/libarchive/commit/3865cf2bcb0eebc1baef28a7841b1cadae6e0f7c Origin: upstream, https://github.com/libarchive/libarchive/commit/e6c9668f3202215ddb71617b41c19b6f05acf008 Bug: https://github.com/libarchive/libarchive/issues/502 Index: libarchive-3.1.2/libarchive/archive_read.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read.c 2013-02-07 22:24:42.000000000 -0500 +++ libarchive-3.1.2/libarchive/archive_read.c 2016-05-13 09:24:42.063300882 -0400 @@ -1394,6 +1394,8 @@ { int64_t skipped; + if (request < 0) + return ARCHIVE_FATAL; if (request == 0) return 0; Index: libarchive-3.1.2/libarchive/archive_read_support_format_cpio.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_cpio.c 2013-01-13 20:43:45.000000000 -0500 +++ libarchive-3.1.2/libarchive/archive_read_support_format_cpio.c 2016-05-13 09:24:39.343272889 -0400 @@ -198,7 +198,7 @@ static int archive_read_format_cpio_read_header(struct archive_read *, struct archive_entry *); static int archive_read_format_cpio_skip(struct archive_read *); -static int be4(const unsigned char *); +static int64_t be4(const unsigned char *); static int find_odc_header(struct archive_read *); static int find_newc_header(struct archive_read *); static int header_bin_be(struct archive_read *, struct cpio *, @@ -213,7 +213,7 @@ struct archive_entry *, size_t *, size_t *); static int is_octal(const char *, size_t); static int is_hex(const char *, size_t); -static int le4(const unsigned char *); +static int64_t le4(const unsigned char *); static int record_hardlink(struct archive_read *a, struct cpio *cpio, struct archive_entry *entry); @@ -944,17 +944,17 @@ return (ARCHIVE_OK); } -static int +static int64_t le4(const unsigned char *p) { - return ((p[0]<<16) + (p[1]<<24) + (p[2]<<0) + (p[3]<<8)); + return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8)); } -static int +static int64_t be4(const unsigned char *p) { - return ((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + (p[3])); + return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3])); } /* debian/patches/CVE-2015-8921.patch0000664000000000000000000000520312741440563013251 0ustar Description: fix read past end of string parsing Origin: backport, https://github.com/libarchive/libarchive/commit/1cbc76faffb79a99c6009a1816736f73b4a3632a Origin: backport, https://github.com/libarchive/libarchive/commit/05a875fdb876e7a2f56a2937f756927cbed919e0 Origin: backport, https://github.com/libarchive/libarchive/commit/90632371f89d1390bf71dd31ae1c842b9110bea2 Origin: backport, https://github.com/libarchive/libarchive/commit/c600d11f2c1645f6f6965592659d386436f4d6db Bug: https://github.com/libarchive/libarchive/issues/512 Index: libarchive-3.1.2/libarchive/archive_entry.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_entry.c 2013-01-13 20:43:45.000000000 -0500 +++ libarchive-3.1.2/libarchive/archive_entry.c 2016-07-13 08:49:51.030721273 -0400 @@ -1588,19 +1588,23 @@ while (*start == '\t' || *start == ' ' || *start == ',') start++; while (*start != '\0') { + size_t length; /* Locate end of token. */ end = start; while (*end != '\0' && *end != '\t' && *end != ' ' && *end != ',') end++; + length = end - start; for (flag = flags; flag->name != NULL; flag++) { - if (memcmp(start, flag->name, end - start) == 0) { + size_t flag_length = strlen(flag->name); + if (length == flag_length + && memcmp(start, flag->name, length) == 0) { /* Matched "noXXXX", so reverse the sense. */ clear |= flag->set; set |= flag->clear; break; - } else if (memcmp(start, flag->name + 2, end - start) - == 0) { + } else if (length == flag_length - 2 + && memcmp(start, flag->name + 2, length) == 0) { /* Matched "XXXX", so don't reverse. */ set |= flag->set; clear |= flag->clear; @@ -1652,19 +1656,23 @@ while (*start == L'\t' || *start == L' ' || *start == L',') start++; while (*start != L'\0') { + size_t length; /* Locate end of token. */ end = start; while (*end != L'\0' && *end != L'\t' && *end != L' ' && *end != L',') end++; + length = end - start; for (flag = flags; flag->wname != NULL; flag++) { - if (wmemcmp(start, flag->wname, end - start) == 0) { + size_t flag_length = wcslen(flag->wname); + if (length == flag_length + && wmemcmp(start, flag->wname, length) == 0) { /* Matched "noXXXX", so reverse the sense. */ clear |= flag->set; set |= flag->clear; break; - } else if (wmemcmp(start, flag->wname + 2, end - start) - == 0) { + } else if (length == flag_length - 2 + && wmemcmp(start, flag->wname + 2, length) == 0) { /* Matched "XXXX", so don't reverse. */ set |= flag->set; clear |= flag->clear; debian/patches/CVE-2016-6250.patch0000664000000000000000000000532013060275670013243 0ustar From 3014e19820ea53c15c90f9d447ca3e668a0b76c6 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 28 May 2016 11:50:39 -0700 Subject: [PATCH] Issue 711: Be more careful about verifying filename lengths when writing ISO9660 archives * Don't cast size_t to int, since this can lead to overflow on machines where sizeof(int) < sizeof(size_t) * Check a + b > limit by writing it as a > limit || b > limit || a + b > limit to avoid problems when a + b wraps around. --- libarchive/archive_write_set_format_iso9660.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) Index: libarchive-3.1.2/libarchive/archive_write_set_format_iso9660.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_write_set_format_iso9660.c 2017-03-09 10:58:45.013476576 -0500 +++ libarchive-3.1.2/libarchive/archive_write_set_format_iso9660.c 2017-03-09 10:58:45.009476533 -0500 @@ -6215,7 +6215,7 @@ unsigned char *p; size_t l; int r; - int ffmax, parent_len; + size_t ffmax, parent_len; static const struct archive_rb_tree_ops rb_ops = { isoent_cmp_node_joliet, isoent_cmp_key_joliet }; @@ -6229,7 +6229,7 @@ else ffmax = 128; - r = idr_start(a, idr, isoent->children.cnt, ffmax, 6, 2, &rb_ops); + r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops); if (r < 0) return (r); @@ -6242,7 +6242,7 @@ int ext_off, noff, weight; size_t lt; - if ((int)(l = np->file->basename_utf16.length) > ffmax) + if ((l = np->file->basename_utf16.length) > ffmax) l = ffmax; p = malloc((l+1)*2); @@ -6275,7 +6275,7 @@ /* * Get a length of MBS of a full-pathname. */ - if ((int)np->file->basename_utf16.length > ffmax) { + if (np->file->basename_utf16.length > ffmax) { if (archive_strncpy_l(&iso9660->mbs, (const char *)np->identifier, l, iso9660->sconv_from_utf16be) != 0 && @@ -6292,7 +6292,9 @@ /* If a length of full-pathname is longer than 240 bytes, * it violates Joliet extensions regulation. */ - if (parent_len + np->mb_len > 240) { + if (parent_len > 240 + || np->mb_len > 240 + || parent_len + np->mb_len > 240) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "The regulation of Joliet extensions;" " A length of a full-pathname of `%s' is " @@ -6304,11 +6306,11 @@ /* Make an offset of the number which is used to be set * hexadecimal number to avoid duplicate identifier. */ - if ((int)l == ffmax) + if (l == ffmax) noff = ext_off - 6; - else if ((int)l == ffmax-2) + else if (l == ffmax-2) noff = ext_off - 4; - else if ((int)l == ffmax-4) + else if (l == ffmax-4) noff = ext_off - 2; else noff = ext_off; debian/patches/CVE-2017-5601.patch0000664000000000000000000000200013060276147013233 0ustar From 98dcbbf0bf4854bf987557e55e55fff7abbf3ea9 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Thu, 19 Jan 2017 22:00:18 +0100 Subject: [PATCH] Fail with negative lha->compsize in lha_read_file_header_1() Fixes a heap buffer overflow reported in Secunia SA74169 --- libarchive/archive_read_support_format_lha.c | 3 +++ 1 file changed, 3 insertions(+) Index: libarchive-3.1.2/libarchive/archive_read_support_format_lha.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_lha.c 2017-03-09 11:01:40.983351017 -0500 +++ libarchive-3.1.2/libarchive/archive_read_support_format_lha.c 2017-03-09 11:01:40.979350974 -0500 @@ -960,6 +960,9 @@ /* Get a real compressed file size. */ lha->compsize -= extdsize - 2; + if (lha->compsize < 0) + goto invalid; /* Invalid compressed file size */ + if (sum_calculated != headersum) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "LHa header sum error"); debian/patches/fix-CVE-2013-0211.patch0000664000000000000000000000136412150214725014010 0ustar Description: Fix CVE-2013-0211: read buffer overflow on 64-bit systems Origin: upstream Bug-Debian: http://bugs.debian.org/703957 Forwarded: not-needed --- libarchive-3.0.4.orig/libarchive/archive_write.c +++ libarchive-3.0.4/libarchive/archive_write.c @@ -665,8 +665,13 @@ static ssize_t _archive_write_data(struct archive *_a, const void *buff, size_t s) { struct archive_write *a = (struct archive_write *)_a; + const size_t max_write = INT_MAX; + archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); + /* In particular, this catches attempts to pass negative values. */ + if (s > max_write) + s = max_write; archive_clear_error(&a->archive); return ((a->format_write_data)(a, buff, s)); } debian/patches/CVE-2016-4302.patch0000664000000000000000000000334112741443603013236 0ustar Description: fix crash via rar files with zero dictionary size Origin: upstream, https://github.com/libarchive/libarchive/commit/05caadc7eedbef471ac9610809ba683f0c698700 Origin: upstream, https://github.com/libarchive/libarchive/commit/5e29e82390bccfff514e710c90de8089ab5ef269 Bug: https://github.com/libarchive/libarchive/issues/719 Index: libarchive-3.1.2/libarchive/archive_ppmd7.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_ppmd7.c 2013-01-13 20:43:45.000000000 -0500 +++ libarchive-3.1.2/libarchive/archive_ppmd7.c 2016-07-13 09:19:32.404160651 -0400 @@ -126,6 +126,11 @@ { if (p->Base == 0 || p->Size != size) { + /* RestartModel() below assumes that p->Size >= UNIT_SIZE + (see the calculation of m->MinContext). */ + if (size < UNIT_SIZE) { + return False; + } Ppmd7_Free(p, alloc); p->AlignOffset = #ifdef PPMD_32BIT Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c 2016-07-13 09:19:15.539950535 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c 2016-07-13 09:19:29.980130454 -0400 @@ -2049,6 +2049,12 @@ rar->range_dec.Stream = &rar->bytein; __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); + if (rar->dictionary_size == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Invalid zero dictionary size"); + return (ARCHIVE_FATAL); + } + if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, rar->dictionary_size, &g_szalloc)) { debian/patches/CVE-2018-1000877.patch0000664000000000000000000000244713417075560013510 0ustar From 021efa522ad729ff0f5806c4ce53e4a6cc1daa31 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Tue, 20 Nov 2018 17:56:29 +1100 Subject: [PATCH] Avoid a double-free when a window size of 0 is specified new_size can be 0 with a malicious or corrupted RAR archive. realloc(area, 0) is equivalent to free(area), so the region would be free()d here and the free()d again in the cleanup function. Found with a setup running AFL, afl-rb, and qsym. --- libarchive/archive_read_support_format_rar.c | 5 +++++ 1 file changed, 5 insertions(+) Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c +++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c @@ -2237,6 +2237,11 @@ parse_codes(struct archive_read *a) new_size = DICTIONARY_MAX_SIZE; else new_size = rar_fls((unsigned int)rar->unp_size) << 1; + if (new_size == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Zero window size is invalid."); + return (ARCHIVE_FATAL); + } new_window = realloc(rar->lzss.window, new_size); if (new_window == NULL) { archive_set_error(&a->archive, ENOMEM, debian/patches/CVE-2016-4300.patch0000664000000000000000000000743112741443342013240 0ustar Description: fix overflow reading 7-Zip with large number of substreams Origin: backport, https://github.com/libarchive/libarchive/commit/3d469df8eaace8297a27ce62befa295c0fdc5a3a Origin: backport, https://github.com/libarchive/libarchive/commit/e79ef306afe332faf22e9b442a2c6b59cb175573 Bug: https://github.com/libarchive/libarchive/issues/718 Index: libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c 2016-07-13 09:17:33.050672178 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c 2016-07-13 09:18:50.907643515 -0400 @@ -324,6 +324,11 @@ char format_name[64]; }; +/* Maximum entry size. This limitation prevents reading intentional + * corrupted 7-zip files on assuming there are not so many entries in + * the files. */ +#define UMAX_ENTRY ARCHIVE_LITERAL_ULL(100000000) + static int archive_read_format_7zip_bid(struct archive_read *, int); static int archive_read_format_7zip_cleanup(struct archive_read *); static int archive_read_format_7zip_read_data(struct archive_read *, @@ -1670,7 +1675,7 @@ return (-1); if (pi->numPackStreams == 0) return (-1); - if (1000000 < pi->numPackStreams) + if (UMAX_ENTRY < pi->numPackStreams) return (-1); /* @@ -1799,12 +1804,12 @@ if (parse_7zip_uint64( a, &(f->coders[i].numInStreams)) < 0) return (-1); - if (1000000 < f->coders[i].numInStreams) + if (UMAX_ENTRY < f->coders[i].numInStreams) return (-1); if (parse_7zip_uint64( a, &(f->coders[i].numOutStreams)) < 0) return (-1); - if (1000000 < f->coders[i].numOutStreams) + if (UMAX_ENTRY < f->coders[i].numOutStreams) return (-1); } @@ -1844,11 +1849,11 @@ for (i = 0; i < f->numBindPairs; i++) { if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0) return (-1); - if (1000000 < f->bindPairs[i].inIndex) + if (UMAX_ENTRY < f->bindPairs[i].inIndex) return (-1); if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0) return (-1); - if (1000000 < f->bindPairs[i].outIndex) + if (UMAX_ENTRY < f->bindPairs[i].outIndex) return (-1); } @@ -1874,7 +1879,7 @@ for (i = 0; i < f->numPackedStreams; i++) { if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0) return (-1); - if (1000000 < f->packedStreams[i]) + if (UMAX_ENTRY < f->packedStreams[i]) return (-1); } } @@ -1916,8 +1921,8 @@ */ if (parse_7zip_uint64(a, &(ci->numFolders)) < 0) goto failed; - if (1000000 < ci->numFolders) - return (-1); + if (UMAX_ENTRY < ci->numFolders) + return (-1); /* * Read External. @@ -1938,7 +1943,7 @@ case 1: if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0) return (-1); - if (1000000 < ci->dataStreamIndex) + if (UMAX_ENTRY < ci->dataStreamIndex) return (-1); if (ci->numFolders > 0) { archive_set_error(&a->archive, -1, @@ -2052,8 +2057,11 @@ for (i = 0; i < numFolders; i++) { if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0) return (-1); - if (1000000 < f[i].numUnpackStreams) + if (UMAX_ENTRY < f[i].numUnpackStreams) + return (-1); + if (unpack_streams > SIZE_MAX - UMAX_ENTRY) { return (-1); + } unpack_streams += (size_t)f[i].numUnpackStreams; } if ((p = header_bytes(a, 1)) == NULL) @@ -2301,8 +2309,8 @@ if (parse_7zip_uint64(a, &(zip->numFiles)) < 0) return (-1); - if (1000000 < zip->numFiles) - return (-1); + if (UMAX_ENTRY < zip->numFiles) + return (-1); zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries)); if (zip->entries == NULL) @@ -2600,7 +2608,7 @@ if (*p) { if (parse_7zip_uint64(a, &(h->dataIndex)) < 0) goto failed; - if (1000000 < h->dataIndex) + if (UMAX_ENTRY < h->dataIndex) goto failed; } debian/patches/Allow-the-option-to-use-no-2nd-stage-compression-wit.patch0000664000000000000000000000176712150214725023562 0ustar Description: Allow the option to use no 2nd stage compression with lrzip. From 21b21bc874f31b1379c2c4feb944970ce4459d5c Mon Sep 17 00:00:00 2001 Origin: upstream --- a/libarchive/archive_write_add_filter_lrzip.c +++ b/libarchive/archive_write_add_filter_lrzip.c @@ -44,7 +44,7 @@ struct write_lrzip { struct archive_write_program_data *pdata; int compression_level; - enum { lzma = 0, bzip2, gzip, lzo, zpaq } compression; + enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression; }; static int archive_write_lrzip_open(struct archive_write_filter *); @@ -107,6 +107,8 @@ data->compression = gzip; else if (strcmp(value, "lzo") == 0) data->compression = lzo; + else if (strcmp(value, "none") == 0) + data->compression = none; else if (strcmp(value, "zpaq") == 0) data->compression = zpaq; else @@ -148,6 +150,9 @@ case lzo: archive_strcat(&as, " -l"); break; + case none: + archive_strcat(&as, " -n"); + break; case zpaq: archive_strcat(&as, " -z"); break; debian/patches/CVE-2016-5844.patch0000664000000000000000000000315512741440002013243 0ustar From 3ad08e01b4d253c66ae56414886089684155af22 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 19 Jun 2016 14:34:37 -0700 Subject: [PATCH] Issue 717: Fix integer overflow when computing location of volume descriptor The multiplication here defaulted to 'int' but calculations of file positions should always use int64_t. A simple cast suffices to fix this since the base location is always 32 bits for ISO, so multiplying by the sector size will never overflow a 64-bit integer. --- libarchive/archive_read_support_format_iso9660.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_iso9660.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_iso9660.c 2016-07-13 09:19:59.300495627 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_iso9660.c 2016-07-13 09:19:59.296495577 -0400 @@ -1089,7 +1089,7 @@ /* This condition is unlikely; by way of caution. */ vd = &(iso9660->joliet); - skipsize = LOGICAL_BLOCK_SIZE * vd->location; + skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location; skipsize = __archive_read_consume(a, skipsize); if (skipsize < 0) return ((int)skipsize); @@ -1127,7 +1127,7 @@ && iso9660->seenJoliet) { /* Switch reading data from primary to joliet. */ vd = &(iso9660->joliet); - skipsize = LOGICAL_BLOCK_SIZE * vd->location; + skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location; skipsize -= iso9660->current_position; skipsize = __archive_read_consume(a, skipsize); if (skipsize < 0) debian/patches/CVE-2017-14503.patch0000664000000000000000000000154513332616541013327 0ustar From 2c8c83b9731ff822fad6cc8c670ea5519c366a14 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Thu, 19 Jul 2018 21:14:53 +0200 Subject: [PATCH] Reject LHA archive entries with negative size. diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c index e14563d..c1c8f58 100644 --- a/libarchive/archive_read_support_format_lha.c +++ b/libarchive/archive_read_support_format_lha.c @@ -737,6 +737,12 @@ archive_read_format_lha_read_header(struct archive_read *a, * Prepare variables used to read a file content. */ lha->entry_bytes_remaining = lha->compsize; + if (lha->entry_bytes_remaining < 0) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Invalid LHa entry size"); + return (ARCHIVE_FATAL); + } lha->entry_offset = 0; lha->entry_crc_calculated = 0; debian/patches/CVE-2016-5418-3.patch0000664000000000000000000003771413060277750013425 0ustar Backport of: From 063ea3ea3fcb569a380b2ebe9c9ddd8bd6ce0d49 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Tue, 9 Aug 2016 21:31:36 -0400 Subject: [PATCH] Test cases for Github Issue #744, #745, and #746. --- Makefile.am | 3 + libarchive/test/CMakeLists.txt | 3 + libarchive/test/main.c | 25 ++++++ libarchive/test/test.h | 3 + libarchive/test/test_write_disk_secure744.c | 95 +++++++++++++++++++++ libarchive/test/test_write_disk_secure745.c | 76 +++++++++++++++++ libarchive/test/test_write_disk_secure746.c | 125 ++++++++++++++++++++++++++++ 7 files changed, 330 insertions(+) create mode 100644 libarchive/test/test_write_disk_secure744.c create mode 100644 libarchive/test/test_write_disk_secure745.c create mode 100644 libarchive/test/test_write_disk_secure746.c Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2017-03-09 11:14:35.863605084 -0500 +++ libarchive-3.1.2/Makefile.am 2017-03-09 11:14:35.859605042 -0500 @@ -453,6 +453,9 @@ libarchive/test/test_write_disk_no_hfs_compression.c \ libarchive/test/test_write_disk_perms.c \ libarchive/test/test_write_disk_secure.c \ + libarchive/test/test_write_disk_secure744.c \ + libarchive/test/test_write_disk_secure745.c \ + libarchive/test/test_write_disk_secure746.c \ libarchive/test/test_write_disk_sparse.c \ libarchive/test/test_write_disk_symlink.c \ libarchive/test/test_write_disk_times.c \ Index: libarchive-3.1.2/libarchive/test/CMakeLists.txt =================================================================== --- libarchive-3.1.2.orig/libarchive/test/CMakeLists.txt 2017-03-09 11:14:35.863605084 -0500 +++ libarchive-3.1.2/libarchive/test/CMakeLists.txt 2017-03-09 11:14:35.859605042 -0500 @@ -168,6 +168,9 @@ test_write_disk_no_hfs_compression.c test_write_disk_perms.c test_write_disk_secure.c + test_write_disk_secure744.c + test_write_disk_secure745.c + test_write_disk_secure746.c test_write_disk_sparse.c test_write_disk_symlink.c test_write_disk_times.c Index: libarchive-3.1.2/libarchive/test/main.c =================================================================== --- libarchive-3.1.2.orig/libarchive/test/main.c 2017-03-09 11:14:35.863605084 -0500 +++ libarchive-3.1.2/libarchive/test/main.c 2017-03-09 11:14:35.859605042 -0500 @@ -1396,6 +1396,31 @@ return (0); } +/* Verify mode of 'pathname'. */ +int +assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) +{ + int mode; + int r; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + failure_start(file, line, "assertFileMode not yet implemented for Windows"); +#else + { + struct stat st; + r = lstat(pathname, &st); + mode = (int)(st.st_mode & 0777); + } + if (r == 0 && mode == expected_mode) + return (1); + failure_start(file, line, "File %s has mode %o, expected %o", + pathname, mode, expected_mode); +#endif + failure_finish(NULL); + return (0); +} + /* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */ int assertion_is_dir(const char *file, int line, const char *pathname, int mode) Index: libarchive-3.1.2/libarchive/test/test.h =================================================================== --- libarchive-3.1.2.orig/libarchive/test/test.h 2017-03-09 11:14:35.863605084 -0500 +++ libarchive-3.1.2/libarchive/test/test.h 2017-03-09 11:14:35.859605042 -0500 @@ -176,6 +176,8 @@ assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks) #define assertFileSize(pathname, size) \ assertion_file_size(__FILE__, __LINE__, pathname, size) +#define assertFileMode(pathname, mode) \ + assertion_file_mode(__FILE__, __LINE__, pathname, mode) #define assertTextFileContents(text, pathname) \ assertion_text_file_contents(__FILE__, __LINE__, text, pathname) #define assertFileContainsLinesAnyOrder(pathname, lines) \ @@ -239,6 +241,7 @@ int assertion_file_nlinks(const char *, int, const char *, int); int assertion_file_not_exists(const char *, int, const char *); int assertion_file_size(const char *, int, const char *, long); +int assertion_file_mode(const char *, int, const char *, int); int assertion_is_dir(const char *, int, const char *, int); int assertion_is_hardlink(const char *, int, const char *, const char *); int assertion_is_not_hardlink(const char *, int, const char *, const char *); Index: libarchive-3.1.2/libarchive/test/test_write_disk_secure744.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_write_disk_secure744.c 2017-03-09 11:16:31.892841034 -0500 @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 2003-2007,2016 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +#define UMASK 022 + +/* + * Github Issue #744 describes a bug in the sandboxing code that + * causes very long pathnames to not get checked for symlinks. + */ + +DEFINE_TEST(test_write_disk_secure744) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + skipping("archive_write_disk security checks not supported on Windows"); +#else + struct archive *a; + struct archive_entry *ae; + size_t buff_size = 8192; + char *buff = malloc(buff_size); + char *p = buff; + int n = 0; + int t; + + assert(buff != NULL); + + /* Start with a known umask. */ + assertUmask(UMASK); + + /* Create an archive_write_disk object. */ + assert((a = archive_write_disk_new()) != NULL); + archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); + + while (p + 500 < buff + buff_size) { + memset(p, 'x', 100); + p += 100; + p[0] = '\0'; + + buff[0] = ((n / 1000) % 10) + '0'; + buff[1] = ((n / 100) % 10)+ '0'; + buff[2] = ((n / 10) % 10)+ '0'; + buff[3] = ((n / 1) % 10)+ '0'; + buff[4] = '_'; + ++n; + + /* Create a symlink pointing to the testworkdir */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, buff); + archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_copy_symlink(ae, testworkdir); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + *p++ = '/'; + sprintf(p, "target%d", n); + + /* Try to create a file through the symlink, should fail. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, buff); + archive_entry_set_mode(ae, S_IFDIR | 0777); + + t = archive_write_header(a, ae); + archive_entry_free(ae); + failure("Attempt to create target%d via %d-character symlink should have failed", n, (int)strlen(buff)); + if(!assertEqualInt(ARCHIVE_FAILED, t)) { + break; + } + } + archive_write_free(a); + free(buff); +#endif +} Index: libarchive-3.1.2/libarchive/test/test_write_disk_secure745.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_write_disk_secure745.c 2017-03-09 11:14:35.859605042 -0500 @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2003-2007,2016 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +#define UMASK 022 + +/* + * Github Issue #745 describes a bug in the sandboxing code that + * allows one to use a symlink to edit the permissions on a file or + * directory outside of the sandbox. + */ + +DEFINE_TEST(test_write_disk_secure745) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + skipping("archive_write_disk security checks not supported on Windows"); +#else + struct archive *a; + struct archive_entry *ae; + + /* Start with a known umask. */ + assertUmask(UMASK); + + /* Create an archive_write_disk object. */ + assert((a = archive_write_disk_new()) != NULL); + archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); + + /* The target dir: The one we're going to try to change permission on */ + assertMakeDir("target", 0700); + + /* The sandbox dir we're going to run inside of. */ + assertMakeDir("sandbox", 0700); + assertChdir("sandbox"); + + /* Create a symlink pointing to the target directory */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "sym"); + archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_copy_symlink(ae, "../target"); + assert(0 == archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Try to alter the target dir through the symlink; this should fail. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "sym"); + archive_entry_set_mode(ae, S_IFDIR | 0777); + assert(0 == archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Permission of target dir should not have changed. */ + assertFileMode("../target", 0700); +#endif +} Index: libarchive-3.1.2/libarchive/test/test_write_disk_secure746.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_write_disk_secure746.c 2017-03-09 11:14:35.859605042 -0500 @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2003-2007,2016 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +#define UMASK 022 + +/* + * Github Issue #746 describes a problem in which hardlink targets are + * not adequately checked and can be used to modify entries outside of + * the sandbox. + */ + +/* + * Verify that ARCHIVE_EXTRACT_SECURE_NODOTDOT disallows '..' in hardlink + * targets. + */ +DEFINE_TEST(test_write_disk_secure746a) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + skipping("archive_write_disk security checks not supported on Windows"); +#else + struct archive *a; + struct archive_entry *ae; + + /* Start with a known umask. */ + assertUmask(UMASK); + + /* The target directory we're going to try to affect. */ + assertMakeDir("target", 0700); + assertMakeFile("target/foo", 0700, "unmodified"); + + /* The sandbox dir we're going to work within. */ + assertMakeDir("sandbox", 0700); + assertChdir("sandbox"); + + /* Create an archive_write_disk object. */ + assert((a = archive_write_disk_new()) != NULL); + archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_NODOTDOT); + + /* Attempt to hardlink to the target directory. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "bar"); + archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_set_size(ae, 8); + archive_entry_copy_hardlink(ae, "../target/foo"); + assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); + assertEqualInt(ARCHIVE_FAILED, archive_write_data(a, "modified", 8)); + archive_entry_free(ae); + + /* Verify that target file contents are unchanged. */ + assertTextFileContents("unmodified", "../target/foo"); +#endif +} + +/* + * Verify that ARCHIVE_EXTRACT_SECURE_NOSYMLINK disallows symlinks in hardlink + * targets. + */ +DEFINE_TEST(test_write_disk_secure746b) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + skipping("archive_write_disk security checks not supported on Windows"); +#else + struct archive *a; + struct archive_entry *ae; + + /* Start with a known umask. */ + assertUmask(UMASK); + + /* The target directory we're going to try to affect. */ + assertMakeDir("target", 0700); + assertMakeFile("target/foo", 0700, "unmodified"); + + /* The sandbox dir we're going to work within. */ + assertMakeDir("sandbox", 0700); + assertChdir("sandbox"); + + /* Create an archive_write_disk object. */ + assert((a = archive_write_disk_new()) != NULL); + archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); + + /* Create a symlink to the target directory. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "symlink"); + archive_entry_copy_symlink(ae, "../target"); + assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Attempt to hardlink to the target directory via the symlink. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "bar"); + archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_set_size(ae, 8); + archive_entry_copy_hardlink(ae, "symlink/foo"); + assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); + assertEqualInt(ARCHIVE_FAILED, archive_write_data(a, "modified", 8)); + archive_entry_free(ae); + + /* Verify that target file contents are unchanged. */ + assertTextFileContents("unmodified", "../target/foo"); +#endif +} debian/patches/CVE-2015-8930.patch0000664000000000000000000000722012741442051013244 0ustar Description: fix segfault via dir loop in malformed ISO Origin: upstream, https://github.com/libarchive/libarchive/commit/39fc59391b7cf2a007bffce280c1e3e66674258f Origin: upstream, https://github.com/libarchive/libarchive/commit/01cfbca4fdae1492a8a09c001b61bbca46f869f2 Bug: https://github.com/libarchive/libarchive/issues/522 Index: libarchive-3.1.2/libarchive/archive_read_support_format_iso9660.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_iso9660.c 2013-01-13 20:43:45.000000000 -0500 +++ libarchive-3.1.2/libarchive/archive_read_support_format_iso9660.c 2016-07-13 09:04:08.052946485 -0400 @@ -387,7 +387,7 @@ static int archive_read_format_iso9660_read_data_skip(struct archive_read *); static int archive_read_format_iso9660_read_header(struct archive_read *, struct archive_entry *); -static const char *build_pathname(struct archive_string *, struct file_info *); +static const char *build_pathname(struct archive_string *, struct file_info *, int); static int build_pathname_utf16be(unsigned char *, size_t, size_t *, struct file_info *); #if DEBUG @@ -1223,6 +1223,7 @@ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Pathname is too long"); + return (ARCHIVE_FATAL); } r = archive_entry_copy_pathname_l(entry, @@ -1245,9 +1246,16 @@ rd_r = ARCHIVE_WARN; } } else { - archive_string_empty(&iso9660->pathname); - archive_entry_set_pathname(entry, - build_pathname(&iso9660->pathname, file)); + const char *path = build_pathname(&iso9660->pathname, file, 0); + if (path == NULL) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Pathname is too long"); + return (ARCHIVE_FATAL); + } else { + archive_string_empty(&iso9660->pathname); + archive_entry_set_pathname(entry, path); + } } iso9660->entry_bytes_remaining = file->size; @@ -1742,12 +1750,12 @@ const unsigned char *isodirrec) { struct iso9660 *iso9660; - struct file_info *file; + struct file_info *file, *filep; size_t name_len; const unsigned char *rr_start, *rr_end; const unsigned char *p; size_t dr_len; - uint64_t fsize; + uint64_t fsize, offset; int32_t location; int flags; @@ -1791,6 +1799,16 @@ return (NULL); } + /* Sanity check that this entry does not create a cycle. */ + offset = iso9660->logical_block_size * (uint64_t)location; + for (filep = parent; filep != NULL; filep = filep->parent) { + if (filep->offset == offset) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Directory structure contains loop"); + return (NULL); + } + } + /* Create a new file entry and copy data from the ISO dir record. */ file = (struct file_info *)calloc(1, sizeof(*file)); if (file == NULL) { @@ -1799,7 +1817,7 @@ return (NULL); } file->parent = parent; - file->offset = iso9660->logical_block_size * (uint64_t)location; + file->offset = offset; file->size = fsize; file->mtime = isodate7(isodirrec + DR_date_offset); file->ctime = file->atime = file->mtime; @@ -3164,10 +3182,17 @@ } static const char * -build_pathname(struct archive_string *as, struct file_info *file) +build_pathname(struct archive_string *as, struct file_info *file, int depth) { + // Plain ISO9660 only allows 8 dir levels; if we get + // to 1000, then something is very, very wrong. + if (depth > 1000) { + return NULL; + } if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) { - build_pathname(as, file->parent); + if (build_pathname(as, file->parent, depth + 1) == NULL) { + return NULL; + } archive_strcat(as, "/"); } if (archive_strlen(&file->name) == 0) debian/patches/CVE-2017-14502.patch0000664000000000000000000000216513417075534013332 0ustar From 5562545b5562f6d12a4ef991fae158bf4ccf92b6 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Sat, 9 Sep 2017 17:47:32 +0200 Subject: [PATCH] Avoid a read off-by-one error for UTF16 names in RAR archives. Reported-By: OSS-Fuzz issue 573 --- libarchive/archive_read_support_format_rar.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c +++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c @@ -1421,7 +1421,11 @@ read_header(struct archive_read *a, stru return (ARCHIVE_FATAL); } filename[filename_size++] = '\0'; - filename[filename_size++] = '\0'; + /* + * Do not increment filename_size here as the computations below + * add the space for the terminating NUL explicitly. + */ + filename[filename_size] = '\0'; /* Decoded unicode form is UTF-16BE, so we have to update a string * conversion object for it. */ debian/patches/CVE-2015-8932.patch0000664000000000000000000001473312741453771013270 0ustar Description: fix crash via invalid compressed data Origin: backport, https://github.com/libarchive/libarchive/commit/f0b1dbbc325a2d922015eee402b72edd422cb9ea Origin: backport, https://github.com/libarchive/libarchive/commit/55ce98e829eda3a4356c2be64a778d8740c2cf6c Origin: backport, https://github.com/libarchive/libarchive/commit/618618c8a6be453f79e0bdbdeab6e1dd8bf429b3 Bug: https://github.com/libarchive/libarchive/issues/547 Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2016-07-13 09:03:30.936507081 -0400 +++ libarchive-3.1.2/Makefile.am 2016-07-13 09:06:04.398321974 -0400 @@ -364,6 +364,7 @@ libarchive/test/test_read_disk_entry_from_file.c \ libarchive/test/test_read_extract.c \ libarchive/test/test_read_file_nonexistent.c \ + libarchive/test/test_read_filter_compress.c \ libarchive/test/test_read_filter_grzip.c \ libarchive/test/test_read_filter_lrzip.c \ libarchive/test/test_read_filter_lzop.c \ Index: libarchive-3.1.2/libarchive/archive_read_support_filter_compress.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_filter_compress.c 2013-01-13 20:43:45.000000000 -0500 +++ libarchive-3.1.2/libarchive/archive_read_support_filter_compress.c 2016-07-13 09:04:44.885382238 -0400 @@ -185,19 +185,22 @@ (void)self; /* UNUSED */ - buffer = __archive_read_filter_ahead(filter, 2, &avail); + /* Shortest valid compress file is 3 bytes. */ + buffer = __archive_read_filter_ahead(filter, 3, &avail); if (buffer == NULL) return (0); bits_checked = 0; + /* First two bytes are the magic value */ if (buffer[0] != 0x1F || buffer[1] != 0x9D) return (0); - bits_checked += 16; - - /* - * TODO: Verify more. - */ + /* Third byte holds compression parameters. */ + if (buffer[2] & 0x20) /* Reserved bit, must be zero. */ + return (0); + if (buffer[2] & 0x40) /* Reserved bit, must be zero. */ + return (0); + bits_checked += 18; return (bits_checked); } @@ -239,7 +242,13 @@ (void)getbits(self, 8); /* Skip first signature byte. */ (void)getbits(self, 8); /* Skip second signature byte. */ + /* Get compression parameters. */ code = getbits(self, 8); + if ((code & 0x1f) > 16) { + archive_set_error(&self->archive->archive, -1, + "Invalid compressed data"); + return (ARCHIVE_FATAL); + } state->maxcode_bits = code & 0x1f; state->maxcode = (1 << state->maxcode_bits); state->use_reset_code = code & 0x80; Index: libarchive-3.1.2/libarchive/test/CMakeLists.txt =================================================================== --- libarchive-3.1.2.orig/libarchive/test/CMakeLists.txt 2016-07-13 09:03:30.936507081 -0400 +++ libarchive-3.1.2/libarchive/test/CMakeLists.txt 2016-07-13 09:05:10.381683711 -0400 @@ -79,6 +79,7 @@ test_read_disk_entry_from_file.c test_read_extract.c test_read_file_nonexistent.c + test_read_filter_compress.c test_read_filter_grzip.c test_read_filter_lrzip.c test_read_filter_lzop.c Index: libarchive-3.1.2/libarchive/test/test_read_filter_compress.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_filter_compress.c 2016-07-13 09:04:44.885382238 -0400 @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2003-2008 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" + +DEFINE_TEST(test_read_filter_compress_truncated) +{ + char data[] = {0x1f, 0x9d}; + struct archive *a; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_FATAL, + archive_read_open_memory(a, data, sizeof(data))); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + + +DEFINE_TEST(test_read_filter_compress_empty2) +{ + char data[] = {0x1f, 0x9d, 0x10}; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, data, sizeof(data))); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify that the format detection worked. */ + assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); + assertEqualString(archive_filter_name(a, 0), "compress (.Z)"); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_EMPTY); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + + +DEFINE_TEST(test_read_filter_compress_invalid) +{ + char data[] = {0x1f, 0x9d, 0x11}; + struct archive *a; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_FATAL, + archive_read_open_memory(a, data, sizeof(data))); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} debian/patches/CVE-2015-8934.patch0000664000000000000000000001455412741450227013264 0ustar From 603454ec03040c29bd051fcc749e3c1433c11a8e Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 19 Jun 2016 15:31:46 -0700 Subject: [PATCH] Issue 521: Properly check reading from lzss decompression buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior code could be tricked into trying to copy data from beyond the end of the internal decompression buffer. Thanks to Hanno Böck for his ongoing fuzz-testing work with libarchive. --- Makefile.am | 1 + libarchive/archive_read_support_format_rar.c | 12 ++++-- libarchive/test/CMakeLists.txt | 1 + libarchive/test/test_read_format_rar_invalid1.c | 44 ++++++++++++++++++++++ .../test/test_read_format_rar_invalid1.rar.uu | 5 +++ 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 libarchive/test/test_read_format_rar_invalid1.c create mode 100644 libarchive/test/test_read_format_rar_invalid1.rar.uu Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2016-07-13 09:13:33.447673843 -0400 +++ libarchive-3.1.2/Makefile.am 2016-07-13 09:14:14.944194122 -0400 @@ -414,6 +414,7 @@ libarchive/test/test_read_format_mtree.c \ libarchive/test/test_read_format_pax_bz2.c \ libarchive/test/test_read_format_rar.c \ + libarchive/test/test_read_format_rar_invalid1.c \ libarchive/test/test_read_format_raw.c \ libarchive/test/test_read_format_tar.c \ libarchive/test/test_read_format_tar_empty_filename.c \ Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c 2016-07-13 09:13:33.447673843 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c 2016-07-13 09:13:33.447673843 -0400 @@ -2798,11 +2798,10 @@ } windowoffs = lzss_offset_for_position(&rar->lzss, startpos); - if(windowoffs + length <= lzss_size(&rar->lzss)) + if(windowoffs + length <= lzss_size(&rar->lzss)) { memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], length); - else - { + } else if (length <= lzss_size(&rar->lzss)) { firstpart = lzss_size(&rar->lzss) - windowoffs; if (firstpart < 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, @@ -2814,9 +2813,14 @@ &rar->lzss.window[windowoffs], firstpart); memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], &rar->lzss.window[0], length - firstpart); - } else + } else { memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], length); + } + } else { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Bad RAR file data"); + return (ARCHIVE_FATAL); } rar->unp_offset += length; if (rar->unp_offset >= rar->unp_buffer_size) Index: libarchive-3.1.2/libarchive/test/CMakeLists.txt =================================================================== --- libarchive-3.1.2.orig/libarchive/test/CMakeLists.txt 2016-07-13 09:13:28.879616543 -0400 +++ libarchive-3.1.2/libarchive/test/CMakeLists.txt 2016-07-13 09:14:27.484351266 -0400 @@ -129,6 +129,7 @@ test_read_format_mtree.c test_read_format_pax_bz2.c test_read_format_rar.c + test_read_format_rar_invalid1.c test_read_format_raw.c test_read_format_tar.c test_read_format_tar_empty_filename.c Index: libarchive-3.1.2/libarchive/test/test_read_format_rar_invalid1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_rar_invalid1.c 2016-07-13 09:13:33.447673843 -0400 @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2003-2016 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_read_format_rar_invalid1) +{ + const char *refname = "test_read_format_rar_invalid1.rar"; + struct archive *a; + struct archive_entry *ae; + char *buff[100]; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buff, 99)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} Index: libarchive-3.1.2/libarchive/test/test_read_format_rar_invalid1.rar.uu =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_rar_invalid1.rar.uu 2016-07-13 09:13:33.447673843 -0400 @@ -0,0 +1,5 @@ +begin 644 test_read_format_rar_invalid1.rar +M4F%R(1H'`,^0B$4= +2,P0`I($``'1E Date: Sat, 21 Feb 2015 09:36:23 -0800 Subject: [PATCH] Issue 407: Tar reader tries to examine last character of an empty filename Of interest: While working on this, I noted that we have an existing test for tar files with empty filenames. That test asserts that the correct behavior here is for the format handler to return the entry with the empty filename and a status of ARCHIVE_OK. Clients need to be robust against empty filenames. --- libarchive/archive_read_support_format_tar.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_tar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_tar.c 2016-07-13 08:59:30.549654085 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_tar.c 2016-07-13 08:59:30.545654037 -0400 @@ -442,6 +442,7 @@ static int default_dev; struct tar *tar; const char *p; + const wchar_t *wp; int r; size_t l, unconsumed = 0; @@ -492,27 +493,22 @@ } } - if (r == ARCHIVE_OK) { + if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) { /* * "Regular" entry with trailing '/' is really * directory: This is needed for certain old tar * variants and even for some broken newer ones. */ - const wchar_t *wp; - wp = archive_entry_pathname_w(entry); - if (wp != NULL) { + if ((wp = archive_entry_pathname_w(entry)) != NULL) { l = wcslen(wp); - if (archive_entry_filetype(entry) == AE_IFREG - && wp[l-1] == L'/') + if (l > 0 && wp[l - 1] == L'/') { archive_entry_set_filetype(entry, AE_IFDIR); - } else { - p = archive_entry_pathname(entry); - if (p == NULL) - return (ARCHIVE_FAILED); + } + } else if ((p = archive_entry_pathname(entry)) != NULL) { l = strlen(p); - if (archive_entry_filetype(entry) == AE_IFREG - && p[l-1] == '/') + if (l > 0 && p[l - 1] == '/') { archive_entry_set_filetype(entry, AE_IFDIR); + } } } return (r); debian/patches/CVE-2016-4809.patch0000664000000000000000000000207012741437771013261 0ustar From fd7e0c02e272913a0a8b6d492c7260dfca0b1408 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 14 May 2016 12:37:37 -0700 Subject: [PATCH] Reject cpio symlinks that exceed 1MB --- libarchive/archive_read_support_format_cpio.c | 5 +++++ 1 file changed, 5 insertions(+) Index: libarchive-3.1.2/libarchive/archive_read_support_format_cpio.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_cpio.c 2016-07-13 09:19:49.756376780 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_cpio.c 2016-07-13 09:19:49.752376731 -0400 @@ -399,6 +399,11 @@ /* If this is a symlink, read the link contents. */ if (archive_entry_filetype(entry) == AE_IFLNK) { + if (cpio->entry_bytes_remaining > 1024 * 1024) { + archive_set_error(&a->archive, ENOMEM, + "Rejecting malformed cpio archive: symlink contents exceed 1 megabyte"); + return (ARCHIVE_FATAL); + } h = __archive_read_ahead(a, (size_t)cpio->entry_bytes_remaining, NULL); if (h == NULL) debian/patches/CVE-2019-1000020.patch0000664000000000000000000000360513426544621013461 0ustar From 8312eaa576014cd9b965012af51bc1f967b12423 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Tue, 1 Jan 2019 17:10:49 +1100 Subject: [PATCH] iso9660: Fail when expected Rockridge extensions is missing A corrupted or malicious ISO9660 image can cause read_CE() to loop forever. read_CE() calls parse_rockridge(), expecting a Rockridge extension to be read. However, parse_rockridge() is structured as a while loop starting with a sanity check, and if the sanity check fails before the loop has run, the function returns ARCHIVE_OK without advancing the position in the file. This causes read_CE() to retry indefinitely. Make parse_rockridge() return ARCHIVE_WARN if it didn't read an extension. As someone with no real knowledge of the format, this seems more apt than ARCHIVE_FATAL, but both the call-sites escalate it to a fatal error immediately anyway. Found with a combination of AFL, afl-rb (FairFuzz) and qsym. --- libarchive/archive_read_support_format_iso9660.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_iso9660.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_iso9660.c +++ libarchive-3.1.2/libarchive/archive_read_support_format_iso9660.c @@ -2098,6 +2098,7 @@ parse_rockridge(struct archive_read *a, const unsigned char *p, const unsigned char *end) { struct iso9660 *iso9660; + int entry_seen = 0; iso9660 = (struct iso9660 *)(a->format->data); @@ -2253,8 +2254,16 @@ parse_rockridge(struct archive_read *a, } p += p[2]; + entry_seen = 1; + } + + if (entry_seen) + return (ARCHIVE_OK); + else { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Tried to parse Rockridge extensions, but none found"); + return (ARCHIVE_WARN); } - return (ARCHIVE_OK); } static int debian/patches/fix-lzo-test-case.patch0000664000000000000000000000562512150214725015125 0ustar Description: This patch fixes test cases for LZO write support in various architectures, such as armhf. Writing a certain amount of files would cause the LZO compressor level 9 to produce a bigger archive than the default compressor level. Author: Andres Mejia --- a/libarchive/test/test_write_filter_lzop.c +++ b/libarchive/test/test_write_filter_lzop.c @@ -39,7 +39,7 @@ size_t buffsize, datasize; char path[16]; size_t used1, used2; - int i, r, use_prog = 0; + int i, r, use_prog = 0, filecount; assert((a = archive_write_new()) != NULL); r = archive_write_add_filter_lzop(a); @@ -58,9 +58,10 @@ datasize = 10000; assert(NULL != (data = (char *)calloc(1, datasize))); + filecount = 10; /* - * Write a 100 files and read them all back. + * Write a filecount files and read them all back. */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); @@ -77,7 +78,7 @@ assert((ae = archive_entry_new()) != NULL); archive_entry_set_filetype(ae, AE_IFREG); archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { + for (i = 0; i < filecount; i++) { sprintf(path, "file%03d", i); archive_entry_copy_pathname(ae, path); assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); @@ -97,7 +98,7 @@ } else { assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { + for (i = 0; i < filecount; i++) { sprintf(path, "file%03d", i); if (!assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae))) @@ -133,7 +134,7 @@ archive_write_set_options(a, "lzop:compression-level=9")); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { + for (i = 0; i < filecount; i++) { sprintf(path, "file%03d", i); assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, path); @@ -161,7 +162,7 @@ archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { + for (i = 0; i < filecount; i++) { sprintf(path, "file%03d", i); if (!assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae))) @@ -186,7 +187,7 @@ archive_write_set_filter_option(a, NULL, "compression-level", "1")); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { + for (i = 0; i < filecount; i++) { sprintf(path, "file%03d", i); assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, path); @@ -216,7 +217,7 @@ } else { assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { + for (i = 0; i < filecount; i++) { sprintf(path, "file%03d", i); if (!assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae))) debian/patches/CVE-2017-14166.patch0000664000000000000000000000156613332616524013340 0ustar From fa7438a0ff4033e4741c807394a9af6207940d71 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Tue, 5 Sep 2017 18:12:19 +0200 Subject: [PATCH] Do something sensible for empty strings to make fuzzers happy. diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c index 780e749..43410e8 100644 --- a/libarchive/archive_read_support_format_xar.c +++ b/libarchive/archive_read_support_format_xar.c @@ -1036,6 +1036,9 @@ atol10(const char *p, size_t char_cnt) uint64_t l; int digit; + if (char_cnt == 0) + return (0); + l = 0; digit = *p - '0'; while (digit >= 0 && digit < 10 && char_cnt-- > 0) { @@ -1050,7 +1053,10 @@ atol8(const char *p, size_t char_cnt) { int64_t l; int digit; - + + if (char_cnt == 0) + return (0); + l = 0; while (char_cnt-- > 0) { if (*p >= '0' && *p <= '7') debian/patches/CVE-2016-10349-and-CVE-2016-10350.patch0000664000000000000000000000216513332616470015541 0ustar From 88eb9e1d73fef46f04677c25b1697b8e25777ed3 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Thu, 1 Dec 2016 19:56:43 +0100 Subject: [PATCH] Reread the CAB header skipping the self-extracting binary code. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15 as found by the "OSS-Fuzz" project. diff --git a/libarchive/archive_read_support_format_cab.c b/libarchive/archive_read_support_format_cab.c index 3c9f94c..88f821b 100644 --- a/libarchive/archive_read_support_format_cab.c +++ b/libarchive/archive_read_support_format_cab.c @@ -643,12 +643,13 @@ cab_read_header(struct archive_read *a) cab = (struct cab *)(a->format->data); if (cab->found_header == 0 && p[0] == 'M' && p[1] == 'Z') { - /* This is an executable? Must be self-extracting... */ + /* This is an executable? Must be self-extracting... */ err = cab_skip_sfx(a); if (err < ARCHIVE_WARN) return (err); - if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL) + /* Re-read header after processing the SFX. */ + if ((p = __archive_read_ahead(a, 42, NULL)) == NULL) return (truncated_error(a)); } debian/patches/Initialize-buff-to-all-zeros.patch0000664000000000000000000000065212150214725017211 0ustar Description: Initialize buff to all zeros. From 1016793be6f7ff9f451a60c997c356ea83759562 Mon Sep 17 00:00:00 2001 Origin: upstream --- a/libarchive/test/test_archive_write_add_filter_by_name.c +++ b/libarchive/test/test_archive_write_add_filter_by_name.c @@ -38,7 +38,7 @@ char *buff; int r; - assert((buff = malloc(buffsize)) != NULL); + assert((buff = calloc(1, buffsize)) != NULL); if (buff == NULL) return; debian/patches/CVE-2015-8922.patch0000664000000000000000000001604712741435176013266 0ustar Backport of: From d094dc02905605ca514baf87855f026b9bf52f1f Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 8 Feb 2015 13:29:51 -0800 Subject: [PATCH] Issue 405: segfault on malformed 7z archive Reject a couple of nonsensical cases. --- Makefile.am | 3 + libarchive/archive_read_support_format_7zip.c | 9 +++ libarchive/test/CMakeLists.txt | 1 + .../test/test_read_format_7zip_malformed.7z.uu | 5 ++ libarchive/test/test_read_format_7zip_malformed.c | 67 ++++++++++++++++++++++ .../test/test_read_format_7zip_malformed2.7z.uu | 5 ++ 6 files changed, 90 insertions(+) create mode 100644 libarchive/test/test_read_format_7zip_malformed.7z.uu create mode 100644 libarchive/test/test_read_format_7zip_malformed.c create mode 100644 libarchive/test/test_read_format_7zip_malformed2.7z.uu Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2016-07-13 08:55:03.730472153 -0400 +++ libarchive-3.1.2/Makefile.am 2016-07-13 08:55:03.726472105 -0400 @@ -372,6 +372,7 @@ libarchive/test/test_read_filter_program_signature.c \ libarchive/test/test_read_filter_uudecode.c \ libarchive/test/test_read_format_7zip.c \ + libarchive/test/test_read_format_7zip_malformed.c \ libarchive/test/test_read_format_ar.c \ libarchive/test/test_read_format_cab.c \ libarchive/test/test_read_format_cab_filename.c \ @@ -598,6 +599,8 @@ libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \ libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \ libarchive/test/test_read_format_7zip_lzma2.7z.uu \ + libarchive/test/test_read_format_7zip_malformed.7z.uu \ + libarchive/test/test_read_format_7zip_malformed2.7z.uu \ libarchive/test/test_read_format_7zip_ppmd.7z.uu \ libarchive/test/test_read_format_7zip_symbolic_name.7z.uu \ libarchive/test/test_read_format_ar.ar.uu \ Index: libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_7zip.c 2016-07-13 08:55:03.730472153 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_7zip.c 2016-07-13 08:55:03.726472105 -0400 @@ -1940,7 +1940,16 @@ return (-1); if (1000000 < ci->dataStreamIndex) return (-1); + if (ci->numFolders > 0) { + archive_set_error(&a->archive, -1, + "Malformed 7-Zip archive"); + goto failed; + } break; + default: + archive_set_error(&a->archive, -1, + "Malformed 7-Zip archive"); + goto failed; } if ((p = header_bytes(a, 1)) == NULL) Index: libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.7z.uu =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_7zip_malformed.7z.uu 2016-07-13 08:55:03.726472105 -0400 @@ -0,0 +1,5 @@ +begin 644 test_read_format_7zip_malformed.7z +M-WJ\KR<<,#"@P/<&!P````````!(`````````&:^$Y Date: Tue, 4 Dec 2018 00:55:22 +1100 Subject: [PATCH] rar: file split across multi-part archives must match Fuzzing uncovered some UAF and memory overrun bugs where a file in a single file archive reported that it was split across multiple volumes. This was caused by ppmd7 operations calling rar_br_fillup. This would invoke rar_read_ahead, which would in some situations invoke archive_read_format_rar_read_header. That would check the new file name against the old file name, and if they didn't match up it would free the ppmd7 buffer and allocate a new one. However, because the ppmd7 decoder wasn't actually done with the buffer, it would continue to used the freed buffer. Both reads and writes to the freed region can be observed. This is quite tricky to solve: once the buffer has been freed it is too late, as the ppmd7 decoder functions almost universally assume success - there's no way for ppmd_read to signal error, nor are there good ways for functions like Range_Normalise to propagate them. So we can't detect after the fact that we're in an invalid state - e.g. by checking rar->cursor, we have to prevent ourselves from ever ending up there. So, when we are in the dangerous part or rar_read_ahead that assumes a valid split, we set a flag force read_header to either go down the path for split files or bail. This means that the ppmd7 decoder keeps a valid buffer and just runs out of data. Found with a combination of AFL, afl-rb and qsym. --- libarchive/archive_read_support_format_rar.c | 9 +++++++++ 1 file changed, 9 insertions(+) Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c +++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c @@ -256,6 +256,7 @@ struct rar struct data_block_offsets *dbo; unsigned int cursor; unsigned int nodes; + char filename_must_match; /* LZSS members */ struct huffman_code maincode; @@ -1498,6 +1499,12 @@ read_header(struct archive_read *a, stru } return ret; } + else if (rar->filename_must_match) + { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Mismatch of file parts split across multi-volume archive"); + return (ARCHIVE_FATAL); + } rar->filename_save = (char*)realloc(rar->filename_save, filename_size + 1); @@ -2862,12 +2869,14 @@ rar_read_ahead(struct archive_read *a, s else if (*avail == 0 && rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER) { + rar->filename_must_match = 1; ret = archive_read_format_rar_read_header(a, a->entry); if (ret == (ARCHIVE_EOF)) { rar->has_endarc_header = 1; ret = archive_read_format_rar_read_header(a, a->entry); } + rar->filename_must_match = 0; if (ret != (ARCHIVE_OK)) return NULL; return rar_read_ahead(a, min, avail); debian/patches/CVE-2016-5418-2.patch0000664000000000000000000003246013060275471013413 0ustar Backport of: From dfd6b54ce33960e420fb206d8872fb759b577ad9 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 11 Sep 2016 13:21:57 -0700 Subject: [PATCH] Fixes for Issue #745 and Issue #746 from Doran Moppert. --- libarchive/archive_write_disk_posix.c | 294 ++++++++++++++++++++++++++-------- 1 file changed, 227 insertions(+), 67 deletions(-) Index: libarchive-3.1.2/libarchive/archive_write_disk_posix.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_write_disk_posix.c 2017-03-09 10:53:10.501913340 -0500 +++ libarchive-3.1.2/libarchive/archive_write_disk_posix.c 2017-03-09 10:55:36.263466001 -0500 @@ -326,12 +326,14 @@ #define HFS_BLOCKS(s) ((s) >> 12) +static int check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags); static int check_symlinks(struct archive_write_disk *); static int create_filesystem_object(struct archive_write_disk *); static struct fixup_entry *current_fixup(struct archive_write_disk *, const char *pathname); #if defined(HAVE_FCHDIR) && defined(PATH_MAX) static void edit_deep_directories(struct archive_write_disk *ad); #endif +static int cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags); static int cleanup_pathname(struct archive_write_disk *); static int create_dir(struct archive_write_disk *, char *); static int create_parent_dir(struct archive_write_disk *, char *); @@ -1996,6 +1998,10 @@ const char *linkname; mode_t final_mode, mode; int r; + /* these for check_symlinks_fsobj */ + char *linkname_copy; /* non-const copy of linkname */ + struct archive_string error_string; + int error_number; /* We identify hard/symlinks according to the link names. */ /* Since link(2) and symlink(2) don't handle modes, we're done here. */ @@ -2004,6 +2010,27 @@ #if !HAVE_LINK return (EPERM); #else + archive_string_init(&error_string); + linkname_copy = strdup(linkname); + if (linkname_copy == NULL) { + return (EPERM); + } + /* TODO: consider using the cleaned-up path as the link target? */ + r = cleanup_pathname_fsobj(linkname_copy, &error_number, &error_string, a->flags); + if (r != ARCHIVE_OK) { + archive_set_error(&a->archive, error_number, "%s", error_string.s); + free(linkname_copy); + /* EPERM is more appropriate than error_number for our callers */ + return (EPERM); + } + r = check_symlinks_fsobj(linkname_copy, &error_number, &error_string, a->flags); + if (r != ARCHIVE_OK) { + archive_set_error(&a->archive, error_number, "%s", error_string.s); + free(linkname_copy); + /* EPERM is more appropriate than error_number for our callers */ + return (EPERM); + } + free(linkname_copy); r = link(linkname, a->name) ? errno : 0; /* * New cpio and pax formats allow hardlink entries @@ -2343,109 +2370,228 @@ * recent paths. */ /* TODO: Extend this to support symlinks on Windows Vista and later. */ + +/* + * Checks the given path to see if any elements along it are symlinks. Returns + * ARCHIVE_OK if there are none, otherwise puts an error in errmsg. + */ static int -check_symlinks(struct archive_write_disk *a) +check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags) { #if !defined(HAVE_LSTAT) /* Platform doesn't have lstat, so we can't look for symlinks. */ (void)a; /* UNUSED */ + (void)path; /* UNUSED */ + (void)error_number; /* UNUSED */ + (void)error_string; /* UNUSED */ + (void)flags; /* UNUSED */ return (ARCHIVE_OK); #else - char *pn; + int res = ARCHIVE_OK; + char *tail; + char *head; + int last; char c; int r; struct stat st; + int restore_pwd; + + /* Nothing to do here if name is empty */ + if(path[0] == '\0') + return (ARCHIVE_OK); /* * Guard against symlink tricks. Reject any archive entry whose * destination would be altered by a symlink. - */ - /* Whatever we checked last time doesn't need to be re-checked. */ - pn = a->name; - if (archive_strlen(&(a->path_safe)) > 0) { - char *p = a->path_safe.s; - while ((*pn != '\0') && (*p == *pn)) - ++p, ++pn; - } - c = pn[0]; - /* Keep going until we've checked the entire name. */ - while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) { + * + * Walk the filename in chunks separated by '/'. For each segment: + * - if it doesn't exist, continue + * - if it's symlink, abort or remove it + * - if it's a directory and it's not the last chunk, cd into it + * As we go: + * head points to the current (relative) path + * tail points to the temporary \0 terminating the segment we're currently examining + * c holds what used to be in *tail + * last is 1 if this is the last tail + */ + restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC); + __archive_ensure_cloexec_flag(restore_pwd); + if (restore_pwd < 0) + return (ARCHIVE_FATAL); + head = path; + tail = path; + last = 0; + /* TODO: reintroduce a safe cache here? */ + /* Skip the root directory if the path is absolute. */ + if(tail == path && tail[0] == '/') + ++tail; + /* Keep going until we've checked the entire name. + * head, tail, path all alias the same string, which is + * temporarily zeroed at tail, so be careful restoring the + * stashed (c=tail[0]) for error messages. + * Exiting the loop with break is okay; continue is not. + */ + while (!last) { + /* Skip the separator we just consumed, plus any adjacent ones */ + while (*tail == '/') + ++tail; /* Skip the next path element. */ - while (*pn != '\0' && *pn != '/') - ++pn; - c = pn[0]; - pn[0] = '\0'; + while (*tail != '\0' && *tail != '/') + ++tail; + /* is this the last path component? */ + last = (tail[0] == '\0') || (tail[0] == '/' && tail[1] == '\0'); + /* temporarily truncate the string here */ + c = tail[0]; + tail[0] = '\0'; /* Check that we haven't hit a symlink. */ - r = lstat(a->name, &st); + r = lstat(head, &st); if (r != 0) { + tail[0] = c; /* We've hit a dir that doesn't exist; stop now. */ if (errno == ENOENT) { break; } else { - /* Note: This effectively disables deep directory + /* Treat any other error as fatal - best to be paranoid here + * Note: This effectively disables deep directory * support when security checks are enabled. * Otherwise, very long pathnames that trigger * an error here could evade the sandbox. * TODO: We could do better, but it would probably * require merging the symlink checks with the * deep-directory editing. */ - return (ARCHIVE_FAILED); + if (error_number) *error_number = errno; + if (error_string) + archive_string_sprintf(error_string, + "Could not stat %s", + path); + res = ARCHIVE_FAILED; + break; + } + } else if (S_ISDIR(st.st_mode)) { + if (!last) { + if (chdir(head) != 0) { + tail[0] = c; + if (error_number) *error_number = errno; + if (error_string) + archive_string_sprintf(error_string, + "Could not chdir %s", + path); + res = (ARCHIVE_FATAL); + break; + } + /* Our view is now from inside this dir: */ + head = tail + 1; } } else if (S_ISLNK(st.st_mode)) { - if (c == '\0') { + if (last) { /* * Last element is symlink; remove it * so we can overwrite it with the * item being extracted. */ - if (unlink(a->name)) { - archive_set_error(&a->archive, errno, - "Could not remove symlink %s", - a->name); - pn[0] = c; - return (ARCHIVE_FAILED); + if (unlink(head)) { + tail[0] = c; + if (error_number) *error_number = errno; + if (error_string) + archive_string_sprintf(error_string, + "Could not remove symlink %s", + path); + res = ARCHIVE_FAILED; + break; } - a->pst = NULL; /* * Even if we did remove it, a warning * is in order. The warning is silly, * though, if we're just replacing one * symlink with another symlink. */ - if (!S_ISLNK(a->mode)) { - archive_set_error(&a->archive, 0, - "Removing symlink %s", - a->name); + tail[0] = c; + /* FIXME: not sure how important this is to restore + if (!S_ISLNK(path)) { + if (error_number) *error_number = 0; + if (error_string) + archive_string_sprintf(error_string, + "Removing symlink %s", + path); } + */ /* Symlink gone. No more problem! */ - pn[0] = c; - return (0); - } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) { + res = ARCHIVE_OK; + break; + } else if (flags & ARCHIVE_EXTRACT_UNLINK) { /* User asked us to remove problems. */ - if (unlink(a->name) != 0) { - archive_set_error(&a->archive, 0, - "Cannot remove intervening symlink %s", - a->name); - pn[0] = c; - return (ARCHIVE_FAILED); + if (unlink(head) != 0) { + tail[0] = c; + if (error_number) *error_number = 0; + if (error_string) + archive_string_sprintf(error_string, + "Cannot remove intervening symlink %s", + path); + res = ARCHIVE_FAILED; + break; } - a->pst = NULL; + tail[0] = c; } else { - archive_set_error(&a->archive, 0, - "Cannot extract through symlink %s", - a->name); - pn[0] = c; - return (ARCHIVE_FAILED); + tail[0] = c; + if (error_number) *error_number = 0; + if (error_string) + archive_string_sprintf(error_string, + "Cannot extract through symlink %s", + path); + res = ARCHIVE_FAILED; + break; } } + /* be sure to always maintain this */ + tail[0] = c; + if (tail[0] != '\0') + tail++; /* Advance to the next segment. */ } - pn[0] = c; - /* We've checked and/or cleaned the whole path, so remember it. */ - archive_strcpy(&a->path_safe, a->name); - return (ARCHIVE_OK); + /* Catches loop exits via break */ + tail[0] = c; +#ifdef HAVE_FCHDIR + /* If we changed directory above, restore it here. */ + if (restore_pwd >= 0) { + r = fchdir(restore_pwd); + if (r != 0) { + if(error_number) *error_number = errno; + if(error_string) + archive_string_sprintf(error_string, + "chdir() failure"); + } + close(restore_pwd); + restore_pwd = -1; + if (r != 0) { + res = (ARCHIVE_FATAL); + } + } +#endif + /* TODO: reintroduce a safe cache here? */ + return res; #endif } +/* + * Check a->name for symlinks, returning ARCHIVE_OK if its clean, otherwise + * calls archive_set_error and returns ARCHIVE_{FATAL,FAILED} + */ +static int +check_symlinks(struct archive_write_disk *a) +{ + struct archive_string error_string; + int error_number; + int rc; + archive_string_init(&error_string); + rc = check_symlinks_fsobj(a->name, &error_number, &error_string, a->flags); + if (rc != ARCHIVE_OK) { + archive_set_error(&a->archive, error_number, "%s", error_string.s); + } + archive_string_free(&error_string); + a->pst = NULL; /* to be safe */ + return rc; +} + + #if defined(__CYGWIN__) /* * 1. Convert a path separator from '\' to '/' . @@ -2519,15 +2665,17 @@ * is set) if the path is absolute. */ static int -cleanup_pathname(struct archive_write_disk *a) +cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags) { char *dest, *src; char separator = '\0'; - dest = src = a->name; + dest = src = path; if (*src == '\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid empty pathname"); + if (error_number) *error_number = ARCHIVE_ERRNO_MISC; + if (error_string) + archive_string_sprintf(error_string, + "Invalid empty pathname"); return (ARCHIVE_FAILED); } @@ -2536,9 +2684,11 @@ #endif /* Skip leading '/'. */ if (*src == '/') { - if (a->flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Path is absolute"); + if (flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) { + if (error_number) *error_number = ARCHIVE_ERRNO_MISC; + if (error_string) + archive_string_sprintf(error_string, + "Path is absolute"); return (ARCHIVE_FAILED); } @@ -2565,10 +2715,11 @@ } else if (src[1] == '.') { if (src[2] == '/' || src[2] == '\0') { /* Conditionally warn about '..' */ - if (a->flags & ARCHIVE_EXTRACT_SECURE_NODOTDOT) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Path contains '..'"); + if (flags & ARCHIVE_EXTRACT_SECURE_NODOTDOT) { + if (error_number) *error_number = ARCHIVE_ERRNO_MISC; + if (error_string) + archive_string_sprintf(error_string, + "Path contains '..'"); return (ARCHIVE_FAILED); } } @@ -2599,7 +2750,7 @@ * We've just copied zero or more path elements, not including the * final '/'. */ - if (dest == a->name) { + if (dest == path) { /* * Nothing got copied. The path must have been something * like '.' or '/' or './' or '/././././/./'. @@ -2614,6 +2765,21 @@ return (ARCHIVE_OK); } +static int +cleanup_pathname(struct archive_write_disk *a) +{ + struct archive_string error_string; + int error_number; + int rc; + archive_string_init(&error_string); + rc = cleanup_pathname_fsobj(a->name, &error_number, &error_string, a->flags); + if (rc != ARCHIVE_OK) { + archive_set_error(&a->archive, error_number, "%s", error_string.s); + } + archive_string_free(&error_string); + return rc; +} + /* * Create the parent directory of the specified path, assuming path * is already in mutable storage. debian/patches/CVE-2016-8687.patch0000664000000000000000000000320613060276023013255 0ustar From e37b620fe8f14535d737e89a4dcabaed4517bf1a Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 21 Aug 2016 10:51:43 -0700 Subject: [PATCH] Issue #767: Buffer overflow printing a filename The safe_fprintf function attempts to ensure clean output for an arbitrary sequence of bytes by doing a trial conversion of the multibyte characters to wide characters -- if the resulting wide character is printable then we pass through the corresponding bytes unaltered, otherwise, we convert them to C-style ASCII escapes. The stack trace in Issue #767 suggest that the 20-byte buffer was getting overflowed trying to format a non-printable multibyte character. This should only happen if there is a valid multibyte character of more than 5 bytes that was unprintable. (Each byte would get expanded to a four-charcter octal-style escape of the form "\123" resulting in >20 characters for the >5 byte multibyte character.) I've not been able to reproduce this, but have expanded the conversion buffer to 128 bytes on the belief that no multibyte character set has a single character of more than 32 bytes. --- tar/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: libarchive-3.1.2/tar/util.c =================================================================== --- libarchive-3.1.2.orig/tar/util.c 2017-03-09 11:00:16.986456278 -0500 +++ libarchive-3.1.2/tar/util.c 2017-03-09 11:00:16.982456235 -0500 @@ -181,7 +181,7 @@ } /* If our output buffer is full, dump it and keep going. */ - if (i > (sizeof(outbuff) - 20)) { + if (i > (sizeof(outbuff) - 128)) { outbuff[i] = '\0'; fprintf(f, "%s", outbuff); i = 0; debian/patches/CVE-2016-10209.patch0000664000000000000000000000324313332616460013322 0ustar From 42a3408ac7df1e69bea9ea12b72e14f59f7400c0 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Mon, 26 Dec 2016 22:23:24 +0100 Subject: [PATCH] archive_strncat_l(): allocate and do not convert if length == 0 This ensures e.g. that archive_mstring_copy_mbs_len_l() does not set aes_set = AES_SET_MBS with aes_mbs.s == NULL. Resolves possible null-pointer dereference reported by OSS-Fuzz. Reported-By: OSS-Fuzz issue 286 diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index 87f9288..c697e83 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -1938,12 +1938,19 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n, struct archive_string_conv *sc) { const void *s; - size_t length; + size_t length = 0; int i, r = 0, r2; + if (_p != NULL && n > 0) { + if (sc != NULL && (sc->flag & SCONV_FROM_UTF16)) + length = utf16nbytes(_p, n); + else + length = mbsnbytes(_p, n); + } + /* We must allocate memory even if there is no data for conversion * or copy. This simulates archive_string_append behavior. */ - if (_p == NULL || n == 0) { + if (length == 0) { int tn = 1; if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) tn = 2; @@ -1959,16 +1966,11 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n, * If sc is NULL, we just make a copy. */ if (sc == NULL) { - length = mbsnbytes(_p, n); if (archive_string_append(as, _p, length) == NULL) return (-1);/* No memory */ return (0); } - if (sc->flag & SCONV_FROM_UTF16) - length = utf16nbytes(_p, n); - else - length = mbsnbytes(_p, n); s = _p; i = 0; if (sc->nconverter > 1) { debian/patches/CVE-2015-8926.patch0000664000000000000000000000272612741435551013266 0ustar From aab73938f8914f0def6cdd5d5be3f142ae7c77f6 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Tue, 3 Mar 2015 20:17:37 -0800 Subject: [PATCH] Issue 410: Segfault on invalid rar archive Libarchive's API passes a void ** which is set by the format to the address of the entry data that was just read. In one particular case, the RAR decompression logic uses a non-NULL value here to indicate that the internal 128k decompression buffer has been filled. But the RAR code took no steps to ensure that the value was set NULL on entry. As a result, a crafted RAR file can trick libarchive into returning to the caller a 128k block of data starting at whatever value was previously in the caller's variable. The fix is simply to set *buff = NULL on entry to the RAR decompression logic. --- libarchive/archive_read_support_format_rar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_rar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_rar.c 2016-07-13 09:00:23.254280686 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_rar.c 2016-07-13 09:00:23.250280638 -0400 @@ -944,8 +944,8 @@ rar->bytes_unconsumed = 0; } + *buff = NULL; if (rar->entry_eof || rar->offset_seek >= rar->unp_size) { - *buff = NULL; *size = 0; *offset = rar->offset; if (*offset < rar->unp_size) debian/patches/CVE-2015-2304.patch0000664000000000000000000001457212504312106013233 0ustar From 59357157706d47c365b2227739e17daba3607526 Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Sun, 1 Mar 2015 12:07:45 +0100 Subject: [PATCH] Add ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS option This fixes a directory traversal in the cpio tool. --- cpio/bsdcpio.1 | 3 ++- cpio/cpio.c | 2 ++ libarchive/archive.h | 2 ++ libarchive/archive_write_disk.3 | 3 +++ libarchive/archive_write_disk_posix.c | 14 +++++++++++--- libarchive/test/test_write_disk_secure.c | 23 +++++++++++++++++++++++ 6 files changed, 43 insertions(+), 4 deletions(-) Index: libarchive-3.1.2/cpio/bsdcpio.1 =================================================================== --- libarchive-3.1.2.orig/cpio/bsdcpio.1 2015-03-24 12:39:08.949869181 -0400 +++ libarchive-3.1.2/cpio/bsdcpio.1 2015-03-24 12:39:08.945869143 -0400 @@ -156,7 +156,8 @@ .It Fl Fl insecure (i and p mode only) Disable security checks during extraction or copying. -This allows extraction via symbolic links and path names containing +This allows extraction via symbolic links, absolute paths, +and path names containing .Sq .. in the name. .It Fl J , Fl Fl xz Index: libarchive-3.1.2/cpio/cpio.c =================================================================== --- libarchive-3.1.2.orig/cpio/cpio.c 2015-03-24 12:39:08.949869181 -0400 +++ libarchive-3.1.2/cpio/cpio.c 2015-03-24 12:39:08.949869181 -0400 @@ -179,6 +179,7 @@ cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS; cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; + cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; cpio->extract_flags |= ARCHIVE_EXTRACT_PERM; cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; cpio->extract_flags |= ARCHIVE_EXTRACT_ACL; @@ -264,6 +265,7 @@ case OPTION_INSECURE: cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; + cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; break; case 'L': /* GNU cpio */ cpio->option_follow_links = 1; Index: libarchive-3.1.2/libarchive/archive.h =================================================================== --- libarchive-3.1.2.orig/libarchive/archive.h 2015-03-24 12:39:08.949869181 -0400 +++ libarchive-3.1.2/libarchive/archive.h 2015-03-24 12:39:08.949869181 -0400 @@ -562,6 +562,8 @@ /* Default: Do not use HFS+ compression if it was not compressed. */ /* This has no effect except on Mac OS v10.6 or later. */ #define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000) +/* Default: Do not reject entries with absolute paths */ +#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000) __LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, int flags); Index: libarchive-3.1.2/libarchive/archive_write_disk.3 =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_write_disk.3 2015-03-24 12:39:08.949869181 -0400 +++ libarchive-3.1.2/libarchive/archive_write_disk.3 2015-03-24 12:39:08.949869181 -0400 @@ -177,6 +177,9 @@ Note that paths ending in .Pa .. always cause an error, regardless of this flag. +.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS +Refuse to extract an absolute path. +The default is to not refuse such paths. .It Cm ARCHIVE_EXTRACT_SPARSE Scan data for blocks of NUL bytes and try to recreate them with holes. This results in sparse files, independent of whether the archive format Index: libarchive-3.1.2/libarchive/archive_write_disk_posix.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_write_disk_posix.c 2015-03-24 12:39:08.949869181 -0400 +++ libarchive-3.1.2/libarchive/archive_write_disk_posix.c 2015-03-24 12:39:08.949869181 -0400 @@ -2504,8 +2504,9 @@ /* * Canonicalize the pathname. In particular, this strips duplicate * '/' characters, '.' elements, and trailing '/'. It also raises an - * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is - * set) any '..' in the path. + * error for an empty path, a trailing '..', (if _SECURE_NODOTDOT is + * set) any '..' in the path or (if ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS + * is set) if the path is absolute. */ static int cleanup_pathname(struct archive_write_disk *a) @@ -2524,8 +2525,15 @@ cleanup_pathname_win(a); #endif /* Skip leading '/'. */ - if (*src == '/') + if (*src == '/') { + if (a->flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Path is absolute"); + return (ARCHIVE_FAILED); + } + separator = *src++; + } /* Scan the pathname one element at a time. */ for (;;) { Index: libarchive-3.1.2/libarchive/test/test_write_disk_secure.c =================================================================== --- libarchive-3.1.2.orig/libarchive/test/test_write_disk_secure.c 2015-03-24 12:39:08.949869181 -0400 +++ libarchive-3.1.2/libarchive/test/test_write_disk_secure.c 2015-03-24 12:39:08.949869181 -0400 @@ -178,6 +178,29 @@ assert(S_ISDIR(st.st_mode)); archive_entry_free(ae); + /* + * Without security checks, we should be able to + * extract an absolute path. + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); + archive_entry_set_mode(ae, S_IFREG | 0777); + assert(0 == archive_write_header(a, ae)); + assert(0 == archive_write_finish_entry(a)); + assertFileExists("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); + assert(0 == unlink("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp")); + + /* But with security checks enabled, this should fail. */ + assert(archive_entry_clear(ae) != NULL); + archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); + archive_entry_set_mode(ae, S_IFREG | 0777); + archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS); + failure("Extracting an absolute path should fail here."); + assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); + archive_entry_free(ae); + assert(0 == archive_write_finish_entry(a)); + assertFileNotExists("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); /* Test the entries on disk. */ debian/patches/CVE-2016-1541.patch0000664000000000000000000000533112715357675013257 0ustar From d0331e8e5b05b475f20b1f3101fe1ad772d7e7e7 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 24 Apr 2016 17:13:45 -0700 Subject: [PATCH] Issue #656: Fix CVE-2016-1541, VU#862384 When reading OS X metadata entries in Zip archives that were stored without compression, libarchive would use the uncompressed entry size to allocate a buffer but would use the compressed entry size to limit the amount of data copied into that buffer. Since the compressed and uncompressed sizes are provided by data in the archive itself, an attacker could manipulate these values to write data beyond the end of the allocated buffer. This fix provides three new checks to guard against such manipulation and to make libarchive generally more robust when handling this type of entry: 1. If an OS X metadata entry is stored without compression, abort the entire archive if the compressed and uncompressed data sizes do not match. 2. When sanity-checking the size of an OS X metadata entry, abort this entry if either the compressed or uncompressed size is larger than 4MB. 3. When copying data into the allocated buffer, check the copy size against both the compressed entry size and uncompressed entry size. --- libarchive/archive_read_support_format_zip.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) Index: libarchive-3.1.2/libarchive/archive_read_support_format_zip.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_zip.c 2016-05-13 09:22:46.746086990 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_zip.c 2016-05-13 09:22:46.742086947 -0400 @@ -560,6 +560,11 @@ switch(rsrc->compression) { case 0: /* No compression. */ + if (rsrc->uncompressed_size != rsrc->compressed_size) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Malformed OS X metadata entry: inconsistent size"); + return (ARCHIVE_FATAL); + } #ifdef HAVE_ZLIB_H case 8: /* Deflate compression. */ #endif @@ -580,6 +585,12 @@ (intmax_t)rsrc->uncompressed_size); return (ARCHIVE_WARN); } + if (rsrc->compressed_size > (4 * 1024 * 1024)) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Mac metadata is too large: %jd > 4M bytes", + (intmax_t)rsrc->compressed_size); + return (ARCHIVE_WARN); + } metadata = malloc((size_t)rsrc->uncompressed_size); if (metadata == NULL) { @@ -619,6 +630,8 @@ bytes_avail = remaining_bytes; switch(rsrc->compression) { case 0: /* No compression. */ + if ((size_t)bytes_avail > metadata_bytes) + bytes_avail = metadata_bytes; memcpy(mp, p, bytes_avail); bytes_used = (size_t)bytes_avail; metadata_bytes -= bytes_used; debian/patches/CVE-2015-8925.patch0000664000000000000000000001364412741452323013262 0ustar Backport of: From 1e18cbb71515a22b2a6f1eb4aaadea461929b834 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 21 Feb 2015 10:37:48 -0800 Subject: [PATCH] Issue 408: Fix escaped newline parsing --- libarchive/archive_read_support_format_mtree.c | 56 ++++++++++++------------- libarchive/test/test_read_format_mtree.c | 8 +++- libarchive/test/test_read_format_mtree.mtree.uu | 20 +++++---- 3 files changed, 45 insertions(+), 39 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_mtree.c 2016-07-13 10:47:57.521323210 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c 2016-07-13 10:47:57.517323158 -0400 @@ -1661,6 +1661,10 @@ c = '\v'; ++src; break; + case '\\': + c = '\\'; + ++src; + break; } } *dest++ = c; @@ -1804,8 +1808,7 @@ ssize_t total_size = 0; ssize_t find_off = 0; const void *t; - const char *s; - void *p; + void *nl; char *u; /* Accumulate line in a line buffer. */ @@ -1816,11 +1819,10 @@ return (0); if (bytes_read < 0) return (ARCHIVE_FATAL); - s = t; /* Start of line? */ - p = memchr(t, '\n', bytes_read); - /* If we found '\n', trim the read. */ - if (p != NULL) { - bytes_read = 1 + ((const char *)p) - s; + nl = memchr(t, '\n', bytes_read); + /* If we found '\n', trim the read to end exactly there. */ + if (nl != NULL) { + bytes_read = ((const char *)nl) - ((const char *)t) + 1; } if (total_size + bytes_read + 1 > limit) { archive_set_error(&a->archive, @@ -1834,38 +1836,34 @@ "Can't allocate working buffer"); return (ARCHIVE_FATAL); } + /* Append new bytes to string. */ memcpy(mtree->line.s + total_size, t, bytes_read); __archive_read_consume(a, bytes_read); total_size += bytes_read; - /* Null terminate. */ mtree->line.s[total_size] = '\0'; - /* If we found an unescaped '\n', clean up and return. */ + for (u = mtree->line.s + find_off; *u; ++u) { if (u[0] == '\n') { + /* Ends with unescaped newline. */ *start = mtree->line.s; return total_size; - } - if (u[0] == '#') { - if (p == NULL) + } else if (u[0] == '#') { + /* Ends with comment sequence #...\n */ + if (nl == NULL) { + /* But we've not found the \n yet */ break; - *start = mtree->line.s; - return total_size; - } - if (u[0] != '\\') - continue; - if (u[1] == '\\') { - ++u; - continue; - } - if (u[1] == '\n') { - memmove(u, u + 1, - total_size - (u - mtree->line.s) + 1); - --total_size; - ++u; - break; + } + } else if (u[0] == '\\') { + if (u[1] == '\n') { + /* Trim escaped newline. */ + total_size -= 2; + mtree->line.s[total_size] = '\0'; + break; + } else if (u[1] != '\0') { + /* Skip the two-char escape sequence */ + ++u; + } } - if (u[1] == '\0') - break; } find_off = u - mtree->line.s; } Index: libarchive-3.1.2/libarchive/test/test_read_format_mtree.c =================================================================== --- libarchive-3.1.2.orig/libarchive/test/test_read_format_mtree.c 2016-07-13 10:47:57.521323210 -0400 +++ libarchive-3.1.2/libarchive/test/test_read_format_mtree.c 2016-07-13 10:48:33.453787196 -0400 @@ -110,6 +110,10 @@ assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/filename\\with_esc\b\t\fapes"); + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(archive_entry_pathname(ae), "notindir"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); @@ -151,7 +155,7 @@ assertEqualInt(archive_entry_mtime(ae), min_time); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(19, archive_file_count(a)); + assertEqualInt(20, archive_file_count(a)); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } Index: libarchive-3.1.2/libarchive/test/test_read_format_mtree.mtree.uu =================================================================== --- libarchive-3.1.2.orig/libarchive/test/test_read_format_mtree.mtree.uu 2016-07-13 10:47:57.521323210 -0400 +++ libarchive-3.1.2/libarchive/test/test_read_format_mtree.mtree.uu 2016-07-13 10:47:57.517323158 -0400 @@ -5,14 +5,16 @@ M9&ER,B!T>7!E/61I<@H@9&ER,V$@='EP93UD:7(*("!I;F1I7!E/61I<@H@(&EN9&ER,V(@ -M='EP93UF:6QE"B`@+BX*("XN"FYO=&EN9&ER('1Y<&4]9FEL90ID:7(R+V9U -M;&QI;F1I7!E/69I;&4@F4]+3$*9&ER,B]B:6=F:6QE('1Y<&4]9FEL92!S:7IE/3DR -M,C,S-S(P,S8X-30W-S4X,#<*9&ER,B]T;V]B:6=F:6QE('1Y<&4]9FEL92!S -M:7IE/3DR,C,S-S(P,S8X-30W-S4X,#@*9&ER,B]V97)Y;VQD9FEL92!T>7!E -M/69I;&4@=&EM93TM.3(R,S,W,C`S-C@U-#7!E/69I +M;&4@F4]+3$*9&ER,B]B:6=F:6QE('1Y +M<&4]9FEL92!S:7IE/3DR,C,S-S(P,S8X-30W-S4X,#<*9&ER,B]T;V]B:6=F +M:6QE('1Y<&4]9FEL92!S:7IE/3DR,C,S-S(P,S8X-30W-S4X,#@*9&ER,B]V +M97)Y;VQD9FEL92!T>7!E/69I;&4@=&EM93TM.3(R,S,W,C`S-C@U-# Date: Sat, 7 Feb 2015 19:03:43 -0800 Subject: [PATCH] Issue 406: Segfault on malformed Zip archive Issue here was reading a size field as a signed number and then using that as an offset. Fixed by correctly masking the size value to an unsigned result. Includes test based on the archive provided in the issue report. --- Makefile.am | 2 + libarchive/archive_read_support_format_zip.c | 4 +- libarchive/test/CMakeLists.txt | 1 + libarchive/test/test_read_format_zip_malformed.c | 61 ++++++++++++++++++++++ .../test/test_read_format_zip_malformed1.zip.uu | 5 ++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 libarchive/test/test_read_format_zip_malformed.c create mode 100644 libarchive/test/test_read_format_zip_malformed1.zip.uu Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2016-07-13 11:31:27.978447322 -0400 +++ libarchive-3.1.2/Makefile.am 2016-07-13 11:31:27.974447272 -0400 @@ -428,6 +428,7 @@ libarchive/test/test_read_format_zip_comment_stored.c \ libarchive/test/test_read_format_zip_filename.c \ libarchive/test/test_read_format_zip_mac_metadata.c \ + libarchive/test/test_read_format_zip_malformed.c \ libarchive/test/test_read_format_zip_sfx.c \ libarchive/test/test_read_large.c \ libarchive/test/test_read_pax_truncated.c \ @@ -684,6 +685,7 @@ libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \ libarchive/test/test_read_format_zip_length_at_end.zip.uu \ libarchive/test/test_read_format_zip_mac_metadata.zip.uu \ + libarchive/test/test_read_format_zip_malformed1.zip.uu \ libarchive/test/test_read_format_zip_sfx.uu \ libarchive/test/test_read_format_zip_symlink.zip.uu \ libarchive/test/test_read_format_zip_ux.zip.uu \ Index: libarchive-3.1.2/libarchive/archive_read_support_format_zip.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_zip.c 2016-07-13 11:31:27.978447322 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_zip.c 2016-07-13 11:31:27.974447272 -0400 @@ -1714,7 +1714,7 @@ if (datasize >= 1 && p[offset] == 1) {/* version=1 */ if (datasize >= 4) { /* get a uid size. */ - uidsize = p[offset+1]; + uidsize = 0xff & (int)p[offset+1]; if (uidsize == 2) zip_entry->uid = archive_le16dec( @@ -1726,7 +1726,7 @@ } if (datasize >= (2 + uidsize + 3)) { /* get a gid size. */ - gidsize = p[offset+2+uidsize]; + gidsize = 0xff & (int)p[offset+2+uidsize]; if (gidsize == 2) zip_entry->gid = archive_le16dec( Index: libarchive-3.1.2/libarchive/test/CMakeLists.txt =================================================================== --- libarchive-3.1.2.orig/libarchive/test/CMakeLists.txt 2016-07-13 11:31:27.978447322 -0400 +++ libarchive-3.1.2/libarchive/test/CMakeLists.txt 2016-07-13 11:31:27.974447272 -0400 @@ -143,6 +143,7 @@ test_read_format_zip_comment_stored.c test_read_format_zip_filename.c test_read_format_zip_mac_metadata.c + test_read_format_zip_malformed.c test_read_format_zip_sfx.c test_read_large.c test_read_pax_truncated.c Index: libarchive-3.1.2/libarchive/test/test_read_format_zip_malformed.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_zip_malformed.c 2016-07-13 11:31:27.974447272 -0400 @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2011 Michihiro NAKAJIMA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +static void +test_malformed1(void) +{ + const char *refname = "test_read_format_zip_malformed1.zip"; + struct archive *a; + struct archive_entry *ae; + char *p; + size_t s; + + extract_reference_file(refname); + + /* Verify with seeking reader. */ + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); + + /* Verify with streaming reader. */ + p = slurpfile(&s, refname); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_malformed) +{ + test_malformed1(); +} Index: libarchive-3.1.2/libarchive/test/test_read_format_zip_malformed1.zip.uu =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_zip_malformed1.zip.uu 2016-07-13 11:31:27.974447272 -0400 @@ -0,0 +1,5 @@ +begin 644 test_read_format_zip_malformed1.zip +M4$L#!#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`$`!P`,#`P,#`P"0`P,#`P,#`P +1,#!U>`L``80P,#`P,#`P,#`` +` +end debian/patches/CVE-2015-8920.patch0000664000000000000000000000536512741434321013254 0ustar From 97f964e3e0ce3ae34bfb4c366a37ba7c0d9610a6 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 7 Feb 2015 12:35:33 -0800 Subject: [PATCH] Issue 403: Buffer underflow parsing 'ar' header While pruning trailing text from ar filenames, we did not check for an empty filename. This results in reading the byte before the filename on the stack. While here, change a number of ar format issues from WARN to FATAL. It's better to abort on a damaged file than risk reading garbage. No doubt, this will require additional tuning in the future. --- libarchive/archive_read_support_format_ar.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) Index: libarchive-3.1.2/libarchive/archive_read_support_format_ar.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_ar.c 2016-07-13 08:49:17.378316133 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_ar.c 2016-07-13 08:49:17.374316085 -0400 @@ -178,7 +178,7 @@ if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) { archive_set_error(&a->archive, EINVAL, "Incorrect file header signature"); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } /* Copy filename into work buffer. */ @@ -237,8 +237,15 @@ * and are not terminated in '/', so we don't trim anything * that starts with '/'.) */ - if (filename[0] != '/' && *p == '/') + if (filename[0] != '/' && p > filename && *p == '/') { *p = '\0'; + } + + if (p < filename) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Found entry with empty filename"); + return (ARCHIVE_FATAL); + } /* * '//' is the GNU filename table. @@ -260,12 +267,12 @@ if (entry_size == 0) { archive_set_error(&a->archive, EINVAL, "Invalid string table"); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } if (ar->strtab != NULL) { archive_set_error(&a->archive, EINVAL, "More than one string tables exist"); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } /* Read the filename table into memory. */ @@ -309,11 +316,11 @@ */ if (ar->strtab == NULL || number > ar->strtab_size) { archive_set_error(&a->archive, EINVAL, - "Can't find long filename for entry"); + "Can't find long filename for GNU/SVR4 archive entry"); archive_entry_copy_pathname(entry, filename); /* Parse the time, owner, mode, size fields. */ ar_parse_common_header(ar, entry, h); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]); @@ -571,7 +578,7 @@ "Invalid string table"); free(ar->strtab); ar->strtab = NULL; - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } static uint64_t debian/patches/Fix-test_archive_write_add_filter_by_name_lrzip-test.patch0000664000000000000000000000176112150214725024326 0ustar Description: Fix test_archive_write_add_filter_by_name_lrzip test case. There's some bug in lrzip where small files cannot use 2nd stage compression. See http://ck-hack.blogspot.com/2012/03/lrzip-0612.html?showComment=1337356929450#c3154145708572533571 From d767d7904781794442938df6b0dd29c8da325e03 Mon Sep 17 00:00:00 2001 Origin: upstream --- a/libarchive/test/test_archive_write_add_filter_by_name.c +++ b/libarchive/test/test_archive_write_add_filter_by_name.c @@ -70,6 +70,16 @@ return; } } + if (filter_code == ARCHIVE_FILTER_LRZIP) + { + /* + * There's a bug in lrzip (as of release 0.612) where 2nd stage + * compression can't be performed on smaller files. Set lrzip to + * use no 2nd stage compression. + */ + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "lrzip:compression=none")); + } assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 10)); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); debian/patches/examples.patch0000664000000000000000000000105512150214725013456 0ustar Description: Add autopkgtest support. Author: Benjamin Drung Applied-Upstream: d19d180efd59d4d3b61e0818eac0d37d086aec55, 453f819252dc15d3cab57534b5a52f314717714b --- a/examples/untar.c +++ b/examples/untar.c @@ -53,7 +53,6 @@ */ #include -__FBSDID("$FreeBSD$"); #include --- a/examples/minitar/minitar.c +++ b/examples/minitar/minitar.c @@ -427,6 +427,9 @@ static void errmsg(const char *m) { + if(m == NULL) { + m = "Error: No error description provided.\n"; + } write(2, m, strlen(m)); } debian/patches/CVE-2016-5418-5.patch0000664000000000000000000000215613060275635013417 0ustar From dc1882e4ab48c3b1c11a596e9f577c43a5592dfb Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Tue, 9 Aug 2016 21:35:38 -0400 Subject: [PATCH] Correct the usage of PATH_MAX as reported in Issue #744. --- libarchive/archive_write_disk_posix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Index: libarchive-3.1.2/libarchive/archive_write_disk_posix.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_write_disk_posix.c 2017-03-09 10:58:18.881198213 -0500 +++ libarchive-3.1.2/libarchive/archive_write_disk_posix.c 2017-03-09 10:58:18.877198170 -0500 @@ -1793,7 +1793,7 @@ char *tail = a->name; /* If path is short, avoid the open() below. */ - if (strlen(tail) <= PATH_MAX) + if (strlen(tail) < PATH_MAX) return; /* Try to record our starting dir. */ @@ -1803,7 +1803,7 @@ return; /* As long as the path is too long... */ - while (strlen(tail) > PATH_MAX) { + while (strlen(tail) >= PATH_MAX) { /* Locate a dir prefix shorter than PATH_MAX. */ tail += PATH_MAX - 8; while (tail > a->name && *tail != '/') debian/patches/examples-offset-type.patch0000664000000000000000000000131412150214725015717 0ustar Description: Fix offset data type in examples. Author: Martin Pitt Bug: http://code.google.com/p/libarchive/issues/detail?id=282 Applied-Upstream: b8bb251083006b8af56c4d099ac4dc5475ce5cbb, 7da8d576848982f2b0264febf89cb8e3f3580af2 --- a/examples/minitar/minitar.c +++ b/examples/minitar/minitar.c @@ -400,7 +400,7 @@ int r; const void *buff; size_t size; - off_t offset; + int64_t offset; for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); --- a/examples/untar.c +++ b/examples/untar.c @@ -199,7 +199,7 @@ int r; const void *buff; size_t size; -#if ARCHIVE_VERSION >= 3000000 +#if ARCHIVE_VERSION_NUMBER >= 3000000 int64_t offset; #else off_t offset; debian/patches/mtree-filename-length-fix.patch0000664000000000000000000000110412150214725016570 0ustar Description: Patch to fix filename length calculation when writing mtree archives. Author: Dave Reisner Origin: upstream --- a/libarchive/archive_write_set_format_mtree.c +++ b/libarchive/archive_write_set_format_mtree.c @@ -1855,9 +1855,9 @@ return (ret); } - /* Make a basename from dirname and slash */ + /* Make a basename from file->parentdir.s and slash */ *slash = '\0'; - file->parentdir.length = slash - dirname; + file->parentdir.length = slash - file->parentdir.s; archive_strcpy(&(file->basename), slash + 1); return (ret); } debian/patches/CVE-2017-14501.patch0000664000000000000000000000551013332616534013323 0ustar From f9569c086ff29259c73790db9cbf39fe8fb9d862 Mon Sep 17 00:00:00 2001 From: John Starks Date: Wed, 25 Jul 2018 12:16:34 -0700 Subject: [PATCH] iso9660: validate directory record length diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c index 1ea7ecf..dc5a9f6 100644 --- a/libarchive/archive_read_support_format_iso9660.c +++ b/libarchive/archive_read_support_format_iso9660.c @@ -409,7 +409,8 @@ static int next_entry_seek(struct archive_read *, struct iso9660 *, struct file_info **); static struct file_info * parse_file_info(struct archive_read *a, - struct file_info *parent, const unsigned char *isodirrec); + struct file_info *parent, const unsigned char *isodirrec, + size_t reclen); static int parse_rockridge(struct archive_read *a, struct file_info *file, const unsigned char *start, const unsigned char *end); @@ -1020,7 +1021,7 @@ read_children(struct archive_read *a, struct file_info *parent) if (*(p + DR_name_len_offset) == 1 && *(p + DR_name_offset) == '\001') continue; - child = parse_file_info(a, parent, p); + child = parse_file_info(a, parent, p, b - p); if (child == NULL) { __archive_read_consume(a, skip_size); return (ARCHIVE_FATAL); @@ -1110,7 +1111,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660) */ seenJoliet = iso9660->seenJoliet;/* Save flag. */ iso9660->seenJoliet = 0; - file = parse_file_info(a, NULL, block); + file = parse_file_info(a, NULL, block, vd->size); if (file == NULL) return (ARCHIVE_FATAL); iso9660->seenJoliet = seenJoliet; @@ -1142,7 +1143,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660) return (ARCHIVE_FATAL); } iso9660->seenJoliet = 0; - file = parse_file_info(a, NULL, block); + file = parse_file_info(a, NULL, block, vd->size); if (file == NULL) return (ARCHIVE_FATAL); iso9660->seenJoliet = seenJoliet; @@ -1747,7 +1748,7 @@ archive_read_format_iso9660_cleanup(struct archive_read *a) */ static struct file_info * parse_file_info(struct archive_read *a, struct file_info *parent, - const unsigned char *isodirrec) + const unsigned char *isodirrec, size_t reclen) { struct iso9660 *iso9660; struct file_info *file, *filep; @@ -1761,7 +1762,11 @@ parse_file_info(struct archive_read *a, struct file_info *parent, iso9660 = (struct iso9660 *)(a->format->data); - dr_len = (size_t)isodirrec[DR_length_offset]; + if (reclen == 0 || reclen < (dr_len = (size_t)isodirrec[DR_length_offset])) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Invalid directory record length"); + return (NULL); + } name_len = (size_t)isodirrec[DR_name_len_offset]; location = archive_le32dec(isodirrec + DR_extent_offset); fsize = toi(isodirrec + DR_size_offset, DR_size_size); debian/patches/CVE-2016-8688.patch0000664000000000000000000001371513060276120013262 0ustar Backport of: From eec077f52bfa2d3f7103b4b74d52572ba8a15aca Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 18 Sep 2016 17:27:47 -0700 Subject: [PATCH] Issue 747 (and others?): Avoid OOB read when parsing multiple long lines The mtree bidder needs to look several lines ahead in the input. It does this by extending the read-ahead and parsing subsequent lines from the same growing buffer. A bookkeeping error when extending the read-ahead would sometimes lead it to significantly over-count the size of the line being read. --- Makefile.am | 1 + libarchive/archive_read_support_format_mtree.c | 11 +++++- libarchive/test/CMakeLists.txt | 1 + libarchive/test/test_read_format_mtree_crash747.c | 44 ++++++++++++++++++++++ .../test_read_format_mtree_crash747.mtree.bz2.uu | 6 +++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 libarchive/test/test_read_format_mtree_crash747.c create mode 100644 libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2017-03-09 11:00:32.530621855 -0500 +++ libarchive-3.1.2/Makefile.am 2017-03-09 11:01:02.050936307 -0500 @@ -412,6 +412,7 @@ libarchive/test/test_read_format_lha.c \ libarchive/test/test_read_format_lha_filename.c \ libarchive/test/test_read_format_mtree.c \ + libarchive/test/test_read_format_mtree_crash747.c \ libarchive/test/test_read_format_pax_bz2.c \ libarchive/test/test_read_format_rar.c \ libarchive/test/test_read_format_rar_invalid1.c \ Index: libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_mtree.c 2017-03-09 11:00:32.530621855 -0500 +++ libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c 2017-03-09 11:00:32.526621812 -0500 @@ -276,6 +276,15 @@ return (avail); } +/* + * <---------------- ravail ---------------------> + * <-- diff ------> <--- avail -----------------> + * <---- len -----------> + * | Previous lines | line being parsed nl extra | + * ^ + * b + * + */ static ssize_t next_line(struct archive_read *a, const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl) @@ -314,7 +323,7 @@ *b += diff; *avail -= diff; tested = len;/* Skip some bytes we already determinated. */ - len = get_line_size(*b, *avail, nl); + len = get_line_size(*b + len, *avail - len, nl); if (len >= 0) len += tested; } Index: libarchive-3.1.2/libarchive/test/CMakeLists.txt =================================================================== --- libarchive-3.1.2.orig/libarchive/test/CMakeLists.txt 2017-03-09 11:00:32.530621855 -0500 +++ libarchive-3.1.2/libarchive/test/CMakeLists.txt 2017-03-09 11:00:32.526621812 -0500 @@ -127,6 +127,7 @@ test_read_format_lha.c test_read_format_lha_filename.c test_read_format_mtree.c + test_read_format_mtree_crash747.c test_read_format_pax_bz2.c test_read_format_rar.c test_read_format_rar_invalid1.c Index: libarchive-3.1.2/libarchive/test/test_read_format_mtree_crash747.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_mtree_crash747.c 2017-03-09 11:00:32.526621812 -0500 @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2003-2016 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" + + +/* + * Reproduce the crash reported in Github Issue #747. + */ +DEFINE_TEST(test_read_format_mtree_crash747) +{ + const char *reffile = "test_read_format_mtree_crash747.mtree.bz2"; + struct archive *a; + + extract_reference_file(reffile); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_bzip2(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_filename(a, reffile, 10240)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + Index: libarchive-3.1.2/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu 2017-03-09 11:00:32.526621812 -0500 @@ -0,0 +1,6 @@ +begin 600 test_read_format_mtree_crash747.mtree.bz2 +M0EIH.3%!62936:OH@(@``'/[@,`0`@!``'^```)A@9\`$`@@`'4)049!IIH! +MM021-0,F@&@6````9%>$(K!GIC*XFR0`$```J0+:$XP```!D-F)H[#SE9+2' +4+E"L=ASXUI%R(I"HD'ZA(5?1`Q`` +` +end debian/patches/CVE-2016-7166.patch0000664000000000000000000001532013060275777013263 0ustar Backport of: From 6e06b1c89dd0d16f74894eac4cfc1327a06ee4a0 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 10 Jan 2015 12:24:58 -0800 Subject: [PATCH] Fix a potential crash issue discovered by Alexander Cherepanov: It seems bsdtar automatically handles stacked compression. This is a nice feature but it could be problematic when it's completely unlimited. Most clearly it's illustrated with quines: $ curl -sRO http://www.maximumcompression.com/selfgz.gz $ (ulimit -v 10000000 && bsdtar -tvf selfgz.gz) bsdtar: Error opening archive: Can't allocate data for gzip decompression Without ulimit, bsdtar will eat all available memory. This could also be a problem for other applications using libarchive. --- Makefile.am | 2 ++ libarchive/archive_read.c | 7 ++-- libarchive/test/CMakeLists.txt | 1 + libarchive/test/test_read_too_many_filters.c | 45 ++++++++++++++++++++++++ libarchive/test/test_read_too_many_filters.gz.uu | 15 ++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 libarchive/test/test_read_too_many_filters.c create mode 100644 libarchive/test/test_read_too_many_filters.gz.uu Index: libarchive-3.1.2/Makefile.am =================================================================== --- libarchive-3.1.2.orig/Makefile.am 2017-03-09 10:58:58.661621957 -0500 +++ libarchive-3.1.2/Makefile.am 2017-03-09 10:59:40.798070797 -0500 @@ -436,6 +436,7 @@ libarchive/test/test_read_pax_truncated.c \ libarchive/test/test_read_position.c \ libarchive/test/test_read_set_format.c \ + libarchive/test/test_read_too_many_filters.c \ libarchive/test/test_read_truncated.c \ libarchive/test/test_read_truncated_filter.c \ libarchive/test/test_sparse_basic.c \ @@ -703,6 +704,7 @@ libarchive/test/test_read_splitted_rar_ab.uu \ libarchive/test/test_read_splitted_rar_ac.uu \ libarchive/test/test_read_splitted_rar_ad.uu \ + libarchive/test/test_read_too_many_filters.gz.uu \ libarchive/test/test_splitted_rar_seek_support_aa.uu \ libarchive/test/test_splitted_rar_seek_support_ab.uu \ libarchive/test/test_splitted_rar_seek_support_ac.uu \ Index: libarchive-3.1.2/libarchive/archive_read.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read.c 2017-03-09 10:58:58.661621957 -0500 +++ libarchive-3.1.2/libarchive/archive_read.c 2017-03-09 10:58:58.657621914 -0500 @@ -544,13 +544,13 @@ static int choose_filters(struct archive_read *a) { - int number_bidders, i, bid, best_bid; + int number_bidders, i, bid, best_bid, n; struct archive_read_filter_bidder *bidder, *best_bidder; struct archive_read_filter *filter; ssize_t avail; int r; - for (;;) { + for (n = 0; n < 25; ++n) { number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); best_bid = 0; @@ -596,6 +596,9 @@ return (ARCHIVE_FATAL); } } + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Input requires too many filters for decoding"); + return (ARCHIVE_FATAL); } /* Index: libarchive-3.1.2/libarchive/test/CMakeLists.txt =================================================================== --- libarchive-3.1.2.orig/libarchive/test/CMakeLists.txt 2017-03-09 10:58:58.661621957 -0500 +++ libarchive-3.1.2/libarchive/test/CMakeLists.txt 2017-03-09 10:58:58.657621914 -0500 @@ -151,6 +151,7 @@ test_read_pax_truncated.c test_read_position.c test_read_set_format.c + test_read_too_many_filters.c test_read_truncated.c test_read_truncated_filter.c test_sparse_basic.c Index: libarchive-3.1.2/libarchive/test/test_read_too_many_filters.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_too_many_filters.c 2017-03-09 10:58:58.657621914 -0500 @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2003-2008,2015 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" + +DEFINE_TEST(test_read_too_many_filters) +{ + const char *name = "test_read_too_many_filters.gz"; + struct archive *a; + int r; + + assert((a = archive_read_new()) != NULL); + r = archive_read_support_filter_gzip(a); + if (r == ARCHIVE_WARN) { + skipping("gzip reading not fully supported on this platform"); + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + extract_reference_file(name); + assertEqualIntA(a, ARCHIVE_FATAL, + archive_read_open_filename(a, name, 200)); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} Index: libarchive-3.1.2/libarchive/test/test_read_too_many_filters.gz.uu =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ libarchive-3.1.2/libarchive/test/test_read_too_many_filters.gz.uu 2017-03-09 10:58:58.657621914 -0500 @@ -0,0 +1,15 @@ +This is a valid gzip file that decompresses to itself, from + http://www.maximumcompression.com/selfgz.gz + +This is used in test_read_too_many_filters to try to +crash libarchive by forcing it to spawn an unending +list of gunzip filters. + +begin 644 test_read_too_many_filters.gz +M'XL(`````````P`/`/#_'XL(`````````P`/`/#_````__\```#__X)QH5P` +M`!X`X?\```#__P```/__@G&A7```'@#A_P```/__````__\```#__P```/__ +M````__\```#__\(FAF`!`!0`Z_\```#__P```/__PB:&8`$`%`#K_\(FAF`! +M`!0`Z_^9(#6-B"@Q,C,T`K/`+```%`#K_P*SP"P``!0`Z_]"B"'$`````/__ +>`P!#2DTAT@```$*((<0`````__\#`$-*32'2```` +` +end debian/patches/CVE-2016-5418-4.patch0000664000000000000000000000672513060275624013422 0ustar From 50952acd22df3326c49771f5e5ba48630899468c Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 11 Sep 2016 13:19:05 -0700 Subject: [PATCH] Fix the test cases for Issue #745 and Issue #746 Thanks to Doran Moppert for pointing out the inconsistencies here. --- libarchive/test/test_write_disk_secure745.c | 5 ++++- libarchive/test/test_write_disk_secure746.c | 16 ++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libarchive/test/test_write_disk_secure745.c b/libarchive/test/test_write_disk_secure745.c index fa6939b..870b064 100644 --- a/libarchive/test/test_write_disk_secure745.c +++ b/libarchive/test/test_write_disk_secure745.c @@ -58,7 +58,7 @@ DEFINE_TEST(test_write_disk_secure745) /* Create a symlink pointing to the target directory */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "sym"); - archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_set_mode(ae, AE_IFLNK | 0777); archive_entry_copy_symlink(ae, "../target"); assert(0 == archive_write_header(a, ae)); archive_entry_free(ae); @@ -72,5 +72,8 @@ DEFINE_TEST(test_write_disk_secure745) /* Permission of target dir should not have changed. */ assertFileMode("../target", 0700); + + assert(0 == archive_write_close(a)); + archive_write_free(a); #endif } diff --git a/libarchive/test/test_write_disk_secure746.c b/libarchive/test/test_write_disk_secure746.c index 0daf1b0..460aafe 100644 --- a/libarchive/test/test_write_disk_secure746.c +++ b/libarchive/test/test_write_disk_secure746.c @@ -63,11 +63,11 @@ DEFINE_TEST(test_write_disk_secure746a) /* Attempt to hardlink to the target directory. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "bar"); - archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_set_mode(ae, AE_IFREG | 0777); archive_entry_set_size(ae, 8); archive_entry_copy_hardlink(ae, "../target/foo"); assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_FAILED, archive_write_data(a, "modified", 8)); + assertEqualInt(ARCHIVE_FATAL, archive_write_data(a, "modified", 8)); archive_entry_free(ae); /* Verify that target file contents are unchanged. */ @@ -105,21 +105,25 @@ DEFINE_TEST(test_write_disk_secure746b) /* Create a symlink to the target directory. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "symlink"); + archive_entry_set_mode(ae, AE_IFLNK | 0777); archive_entry_copy_symlink(ae, "../target"); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); archive_entry_free(ae); /* Attempt to hardlink to the target directory via the symlink. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "bar"); - archive_entry_set_mode(ae, S_IFREG | 0777); + archive_entry_set_mode(ae, AE_IFREG | 0777); archive_entry_set_size(ae, 8); archive_entry_copy_hardlink(ae, "symlink/foo"); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_FAILED, archive_write_data(a, "modified", 8)); + assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); + assertEqualIntA(a, ARCHIVE_FATAL, archive_write_data(a, "modified", 8)); archive_entry_free(ae); /* Verify that target file contents are unchanged. */ assertTextFileContents("unmodified", "../target/foo"); + + assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a)); + archive_write_free(a); #endif } debian/patches/CVE-2015-8931.patch0000664000000000000000000000426712741442321013255 0ustar Description: fix integer overflow parsing time values Origin: backport, https://github.com/libarchive/libarchive/commit/b31744df71084a8734f97199e42418f55d08c6c5 Origin: backport, https://github.com/libarchive/libarchive/commit/c0c52e9aaafb0860c4151c5374372051e9354301 Bug: https://github.com/libarchive/libarchive/issues/539 Index: libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c =================================================================== --- libarchive-3.1.2.orig/libarchive/archive_read_support_format_mtree.c 2016-07-13 09:03:42.596645150 -0400 +++ libarchive-3.1.2/libarchive/archive_read_support_format_mtree.c 2016-07-13 09:04:23.785132641 -0400 @@ -137,16 +137,22 @@ #if defined(TIME_T_MAX) return TIME_T_MAX; #else - static time_t t; - time_t a; - if (t == 0) { - a = 1; - while (a > t) { - t = a; - a = a * 2 + 1; + /* ISO C allows time_t to be a floating-point type, + but POSIX requires an integer type. The following + should work on any system that follows the POSIX + conventions. */ + if (((time_t)0) < ((time_t)-1)) { + /* Time_t is unsigned */ + return (~(time_t)0); + } else { + /* Time_t is signed. */ + /* Assume it's the same as int64_t or int32_t */ + if (sizeof(time_t) == sizeof(int64_t)) { + return (time_t)INT64_MAX; + } else { + return (time_t)INT32_MAX; } } - return t; #endif } @@ -156,20 +162,17 @@ #if defined(TIME_T_MIN) return TIME_T_MIN; #else - /* 't' will hold the minimum value, which will be zero (if - * time_t is unsigned) or -2^n (if time_t is signed). */ - static int computed; - static time_t t; - time_t a; - if (computed == 0) { - a = (time_t)-1; - while (a < t) { - t = a; - a = a * 2; - } - computed = 1; + if (((time_t)0) < ((time_t)-1)) { + /* Time_t is unsigned */ + return (time_t)0; + } else { + /* Time_t is signed. */ + if (sizeof(time_t) == sizeof(int64_t)) { + return (time_t)INT64_MIN; + } else { + return (time_t)INT32_MIN; + } } - return t; #endif } @@ -1460,7 +1463,7 @@ int64_t m; int64_t my_time_t_max = get_time_t_max(); int64_t my_time_t_min = get_time_t_min(); - long ns; + long ns = 0; *parsed_kws |= MTREE_HAS_MTIME; m = mtree_atol10(&val); debian/changelog0000664000000000000000000006742513426545333011070 0ustar libarchive (3.1.2-7ubuntu2.8) trusty-security; urgency=medium * SECURITY UPDATE: Denial of service - debian/patches/CVE-2019-1000019.patch: fix in libarchive/archive_read_support_format_7zip.c. - CVE-2019-1000019 * SECURITY UPDATE: Denial of service - debian/patches/CVE-2019-1000020.patch: fix in libarchive/archive_read_support_format_iso9660.c. - CVE-2019-1000020 -- Leonidas S. Barbosa Wed, 06 Feb 2019 08:48:45 -0300 libarchive (3.1.2-7ubuntu2.7) trusty-security; urgency=medium * SECURITY UPDATE: Out-of-bounds read - debian/patches/CVE-2017-14502.patch: fix in libarchive/archive_read_support_format_rar.c. - CVE-2017-14502 * SECURITY UPDATE: Denial of service - debian/patches/CVE-2018-1000877.patch: fix in libarchive/archive_read_support_format_rar.c. - CVE-2018-1000877 * SECURITY UPDATE: Denial of service - debian/patches/CVE-2018-1000878.patch: fix in libarchive/archive_read_support_format_rar.c. - CVE-2018-1000878 -- Leonidas S. Barbosa Mon, 14 Jan 2019 09:08:38 -0300 libarchive (3.1.2-7ubuntu2.6) trusty-security; urgency=medium * SECURITY UPDATE: Denial of service - debian/patches/CVE-2016-10209.patch: fix in libarchive/archive_string.c. - CVE-2016-10209 * SECURITY UPDATE: Denial of service - debian/patches/CVE-2016-10349-and-CVE-2016-10350.patch: fix in libarchive/archive_read_support_format_cab.c. - CVE-2016-10349 - CVE-2016-10350 * SECURITY UPDATE: Denial of service - debian/patches/CVE-2017-14166.patch: fix in libarchive/archive_read_support_format_xar.c. - CVE-2017-14166 * SECURITY UPDATE: Out-of-bounds read - debian/patches/CVE-2017-14501.patch: fix in libarchive/archive_read_support_format_iso9660.c. - CVE-2017-14501 * SECURITY UPDATE: Out-of-bounds read - debian/patches/CVE-2017-14503.patch: fix in libarchive/archive_read_support_format_lha.c. - CVE-2017-14503 -- Leonidas S. Barbosa Wed, 08 Aug 2018 13:42:39 -0300 libarchive (3.1.2-7ubuntu2.4) trusty-security; urgency=medium * SECURITY UPDATE: arbitrary file write via hardlink entries - debian/patches/CVE-2016-5418-1.patch: enforce sandbox with very long pathnames in libarchive/archive_write_disk_posix.c. - debian/patches/CVE-2016-5418-2.patch: fix path handling in libarchive/archive_write_disk_posix.c. - debian/patches/CVE-2016-5418-3.patch: add test cases to Makefile.am, libarchive/test/CMakeLists.txt, libarchive/test/main.c, libarchive/test/test.h, libarchive/test/test_write_disk_secure744.c, libarchive/test/test_write_disk_secure745.c, libarchive/test/test_write_disk_secure746.c. - debian/patches/CVE-2016-5418-4.patch: fix testcases in libarchive/test/test_write_disk_secure745.c, libarchive/test/test_write_disk_secure746.c. - debian/patches/CVE-2016-5418-5.patch: correct PATH_MAX usage in libarchive/archive_write_disk_posix.c. - CVE-2016-5418 * SECURITY UPDATE: denial of service and possible code execution when writing an ISO9660 archive - debian/patches/CVE-2016-6250.patch: check for overflow in libarchive/archive_write_set_format_iso9660.c. - CVE-2016-6250 * SECURITY UPDATE: denial of service via recursive decompression - debian/patches/CVE-2016-7166.patch: limit number of filters in libarchive/archive_read.c, added test to Makefile.am, libarchive/test/CMakeLists.txt, libarchive/test/test_read_too_many_filters.c, libarchive/test/test_read_too_many_filters.gz.uu. - CVE-2016-7166 * SECURITY UPDATE: denial of service via non-printable multibyte character in a filename - debian/patches/CVE-2016-8687.patch: expand buffer size in tar/util.c. - CVE-2016-8687 * SECURITY UPDATE: denial of service via multiple long lines - debian/patches/CVE-2016-8688.patch: fix bounds in libarchive/archive_read_support_format_mtree.c, added test to Makefile.am, libarchive/test/CMakeLists.txt, libarchive/test/test_read_format_mtree_crash747.c, libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu. - CVE-2016-8688 * SECURITY UPDATE: denial of service via multiple EmptyStream attributes - debian/patches/CVE-2016-8689.patch: reject files with multiple markers in libarchive/archive_read_support_format_7zip.c. - CVE-2016-8689 * SECURITY UPDATE: denial of service via invalid compressed file size - debian/patches/CVE-2017-5601.patch: add check to libarchive/archive_read_support_format_lha.c. - CVE-2017-5601 -- Marc Deslauriers Thu, 09 Mar 2017 11:23:19 -0500 libarchive (3.1.2-7ubuntu2.3) trusty-security; urgency=medium * SECURITY UPDATE: denial of service via malformed rar or cab files - debian/patches/CVE-2015-8916.patch: ignore entries with empty filenames in tar/read.c. - CVE-2015-8916 - CVE-2015-8917 * SECURITY UPDATE: denial of service via malformed lzh file - debian/patches/CVE-2015-8919.patch: recognize empty dir name in libarchive/archive_read_support_format_lha.c. - CVE-2015-8919 * SECURITY UPDATE: buffer underflow parsing ar header - debian/patches/CVE-2015-8920.patch: check for empty filenames in libarchive/archive_read_support_format_ar.c. - CVE-2015-8920 * SECURITY UPDATE: read past end of string parsing - debian/patches/CVE-2015-8921.patch: properly calculate string length in libarchive/archive_entry.c. - CVE-2015-8921 * SECURITY UPDATE: segfault on malformed 7z archive - debian/patches/CVE-2015-8922.patch: reject some malformed files in libarchive/archive_read_support_format_7zip.c, added tests to Makefile.am, libarchive/test/test_read_format_7zip_malformed.7z.uu, libarchive/test/test_read_format_7zip_malformed.c, libarchive/test/test_read_format_7zip_malformed2.7z.uu, libarchive/test/CMakeLists.txt. - CVE-2015-8922 * SECURITY UPDATE: segfault on malformed Zip archive - debian/patches/CVE-2015-8923.patch: properly handle sizes in libarchive/archive_read_support_format_zip.c, added tests to Makefile.am, libarchive/test/CMakeLists.txt, libarchive/test/test_read_format_zip_malformed.c, libarchive/test/test_read_format_zip_malformed1.zip.uu. - CVE-2015-8923 * SECURITY UPDATE: buffer overflow when processing tar files - debian/patches/CVE-2015-8924.patch: properly handle empty filenames in libarchive/archive_read_support_format_tar.c. - CVE-2015-8924 * SECURITY UPDATE: improper newline parsing - debian/patches/CVE-2015-8925.patch: fix escaped newline parsing in libarchive/archive_read_support_format_mtree.c, added tests to libarchive/test/test_read_format_mtree.c, libarchive/test/test_read_format_mtree.mtree.uu. - CVE-2015-8925 * SECURITY UPDATE: segfault on invalid rar archive - debian/patches/CVE-2015-8926.patch: properly handle return code in libarchive/archive_read_support_format_rar.c. - CVE-2015-8926 * SECURITY UPDATE: out-of-bounds read in mtree - debian/patches/CVE-2015-8928.patch: properly handle filename parsing in libarchive/archive_read_support_format_mtree.c. - CVE-2015-8928 * SECURITY UPDATE: segfault via dir loop in malformed ISO - debian/patches/CVE-2015-8930.patch: limit recursion in libarchive/archive_read_support_format_iso9660.c. - CVE-2015-8930 * SECURITY UPDATE: integer overflow parsing time values - debian/patches/CVE-2015-8931.patch: fix time handling in libarchive/archive_read_support_format_mtree.c. - CVE-2015-8931 * SECURITY UPDATE: crash via invalid compressed data - debian/patches/CVE-2015-8932.patch: add more checks to libarchive/archive_read_support_filter_compress.c, added tests to Makefile.am, libarchive/test/CMakeLists.txt, libarchive/test/test_read_filter_compress.c. - CVE-2015-8932 * SECURITY UPDATE: integer overflow via negative-sized sparse blocks - debian/patches/CVE-2015-8933.patch: add check to libarchive/archive_read_support_format_tar.c. - CVE-2015-8933 * SECURITY UPDATE: heap overflow parsing malformed tar archives - debian/patches/CVE-2015-8934.patch: properly check reading from lzss decompression buffer in libarchive/archive_read_support_format_rar.c, added tests to Makefile.am, libarchive/test/CMakeLists.txt, libarchive/test/test_read_format_rar_invalid1.c, libarchive/test/test_read_format_rar_invalid1.rar.uu. - CVE-2015-8934 * SECURITY UPDATE: overflow reading 7-Zip with large number of substreams - debian/patches/CVE-2016-4300.patch: add another limit to libarchive/archive_read_support_format_7zip.c. - CVE-2016-4300 * SECURITY UPDATE: crash via rar files with zero dictionary size - debian/patches/CVE-2016-4302.patch: handle zero-sized disctionary in libarchive/archive_ppmd7.c, libarchive/archive_read_support_format_rar.c. - CVE-2016-4302 * SECURITY UPDATE: memory allocation issues with large cpio symlinks - debian/patches/CVE-2016-4809.patch: reject large symlinks in libarchive/archive_read_support_format_cpio.c. - CVE-2016-4809 * SECURITY UPDATE: integer overflow when computing volume descriptor - debian/patches/CVE-2016-5844.patch: fix multiplications in libarchive/archive_read_support_format_iso9660.c. - CVE-2016-5844 -- Marc Deslauriers Wed, 13 Jul 2016 11:23:39 -0400 libarchive (3.1.2-7ubuntu2.2) trusty-security; urgency=medium * SECURITY UPDATE: code execution via incorrect compressed size - debian/patches/CVE-2016-1541.patch: check sizes in libarchive/archive_read_support_format_zip.c. - CVE-2016-1541 * SECURITY UPDATE: denial of service via malformed cpio archive - debian/patches/issue502.patch: fix implicit cast in libarchive/archive_read_support_format_cpio.c, reject attempts to move the file pointer by a negative amount in libarchive/archive_read.c. - CVE number pending. -- Marc Deslauriers Fri, 13 May 2016 10:08:06 -0400 libarchive (3.1.2-7ubuntu2.1) trusty-security; urgency=medium * SECURITY UPDATE: absolute path traversal vulnerability in bsdcpio - debian/patches/CVE-2015-2304.patch: don't allow absolute paths by default in cpio/cpio.c, libarchive/archive.h, libarchive/archive_write_disk_posix.c, added test to libarchive/test/test_write_disk_secure.c, updated documentation in cpio/bsdcpio.1, libarchive/archive_write_disk.3. - CVE-2015-2304 -- Marc Deslauriers Tue, 24 Mar 2015 12:43:54 -0400 libarchive (3.1.2-7ubuntu2) trusty; urgency=medium * Build using dh-autoreconf. -- Matthias Klose Sat, 14 Dec 2013 13:40:40 +0100 libarchive (3.1.2-7ubuntu1) trusty; urgency=low * debian/tests/minitar: - Fix minitar dep8 test to check for application/gzip rather than application/x-gzip -- Michael Terry Wed, 11 Dec 2013 11:36:08 -0500 libarchive (3.1.2-7) unstable; urgency=low * Upload to unstable. -- Andres Mejia Sat, 25 May 2013 16:07:06 -0400 libarchive (3.1.2-6) experimental; urgency=low [ Andreas Henriksson ] * Merge debian-wheezy branch containing package revision 3.0.4-3. [ Andres Mejia ] * Remove gbp config overrides. * Remove lrzip build dependency as test cases fail on certain architectures. -- Andres Mejia Tue, 07 May 2013 21:44:50 -0400 libarchive (3.1.2-5) experimental; urgency=low * Update patch to fix LZO test cases to use changes from upstream. * Update homepage field for new homepage URL. * Add upstream changes to fix building libarchive with lrzip support. -- Andres Mejia Sun, 24 Feb 2013 16:44:32 -0500 libarchive (3.1.2-4) experimental; urgency=low * Add mtree filename length fix from upstream. * Add fix for LZO test cases. * Renable LZO support. * Bump Standards-Version to 3.9.4. -- Andres Mejia Sat, 23 Feb 2013 23:44:26 -0500 libarchive (3.1.2-3) experimental; urgency=low * Update gbp.conf to point to branches used for libarchive packaging in experimental. * Disable LZO support, it is broken on some architectures. -- Andres Mejia Sun, 10 Feb 2013 12:43:35 -0500 libarchive (3.1.2-2) experimental; urgency=low * Update patches to use changes applied upstream. -- Andres Mejia Sat, 09 Feb 2013 15:13:20 -0500 libarchive (3.1.2-1) experimental; urgency=low * New upstream release. * Enable LZO support. -- Andres Mejia Sat, 09 Feb 2013 13:37:34 -0500 libarchive (3.1.1-1) experimental; urgency=low * New upstream release. -- Andres Mejia Wed, 16 Jan 2013 17:06:36 -0500 libarchive (3.1.0-1) experimental; urgency=low [ Benjamin Drung ] * Add autopkgtest (LP: #1073390). [ Martin Pitt ] * Add examples-offset-type.patch: Fix offset data type in examples. [ Andres Mejia ] * New upstream release. -- Andres Mejia Sun, 13 Jan 2013 22:00:14 -0500 libarchive (3.0.4-3) unstable; urgency=low * Add patch that fixes CVE-2013-0211. (Closes: #703957) -- Andreas Henriksson Wed, 27 Mar 2013 16:20:36 +0100 libarchive (3.0.4-2) unstable; urgency=low * Add debian/patches/gcc-4.7-fixes-from-upstream.patch (Closes: #674368, #672690) -- Andreas Henriksson Thu, 24 May 2012 14:49:41 +0200 libarchive (3.0.4-1) unstable; urgency=low * New upstream release. * Patches removed, applied upstream. -- Andres Mejia Thu, 29 Mar 2012 09:44:15 -0400 libarchive (3.0.3-7) unstable; urgency=low * Allow the dev package to be multi-arch installable. * Set verbosity level to 1 for test programs. This incorporates upstream commit 7cd65cd07cfa2693455d174049b4887434041695. (Closes: #662716) * Fixup package description about ISO support. (Closes: #659651) -- Andres Mejia Fri, 16 Mar 2012 16:21:21 -0400 libarchive (3.0.3-6) unstable; urgency=low * Add patch to fix infinite loop in xps files (Closes: #662603) - Thanks for the patch to Savvas Radevic! -- Andreas Henriksson Mon, 05 Mar 2012 16:23:05 +0100 libarchive (3.0.3-5) unstable; urgency=low * Detect if locales or locales-all is installed for use with test suite. * Bump Standards-Version to 3.9.3. -- Andres Mejia Thu, 23 Feb 2012 19:29:24 -0500 libarchive (3.0.3-4) unstable; urgency=low * Ensure tests are not run via root. (Closes: #659294) -- Andres Mejia Tue, 21 Feb 2012 16:01:26 -0500 libarchive (3.0.3-3) unstable; urgency=low * Update watch file to use new home for downloads. -- Andres Mejia Mon, 06 Feb 2012 17:04:34 -0500 libarchive (3.0.3-2) unstable; urgency=low * Upload to unstable. * Update homepage to libarchive's new home. -- Andres Mejia Mon, 06 Feb 2012 16:37:07 -0500 libarchive (3.0.3-1) experimental; urgency=low * New upstream release. * Fix for hurd build failure included in new release. (Closes: #653458) * Update copyright file. -- Andres Mejia Mon, 16 Jan 2012 11:49:46 -0500 libarchive (3.0.2-3) experimental; urgency=low * Prepare an upload to experimental. -- Andres Mejia Sat, 24 Dec 2011 20:39:17 -0500 libarchive (3.0.2-1) unstable; urgency=low * Prepare new upstream release. * Update package descriptions, deleting some information that doesn't apply to current build of packages. * Rename shared library package for soname bump. * Remove symbols files. Symbols file needs to be maintained better. Also, numerous symbols were in the file which were meant to stay private (all the __archive_* symbols for example). -- Andres Mejia Sat, 24 Dec 2011 15:47:39 -0500 libarchive (3.0.1b-1) experimental; urgency=low * Package latest testing release. * Update debian/control, noting new 7zip support. * Fix package description for bsdcpio. * Update symbols file for new symbols added in libarchive-3.0.1b. -- Andres Mejia Fri, 16 Dec 2011 17:28:03 -0500 libarchive (3.0.0a-1) experimental; urgency=low * Package testing release of libarchive for experimental. * Better ext2 file attribute/flag support included in new release. (Closes: #615875) * Remove all patches, applied in upstream source. * Add option to unapply patches for dpkg-source v3. * Change package name libarchive1 to libarchive11 to match soname bump. * Rename files used in packaging libarchive11. * Build depend on Nettle library. * Add mention of rar support in package description. * Remove installation of symlink for libarchive library file. * Explicitely build without openssl and with nettle support. * Add proper depends to new libarchive11 package. * Update symbols file for libarchive11. * Ensure bsdtar and bsdcpio are linked to shared library dynamically. * Build en_US.UTF-8 locale at runtime to pass test suite. -- Andres Mejia Fri, 16 Dec 2011 16:31:37 -0500 libarchive (2.8.5-5) unstable; urgency=medium * Backport fixes for fix for CVE-2011-1777 and CVE-2011-1778. (Closes: #651844) * Fix build failure for GNU/Hurd. (Closes: #651995) * Regenerate autoreconf patch. -- Andres Mejia Wed, 14 Dec 2011 12:18:31 -0500 libarchive (2.8.5-4) unstable; urgency=low [ Andres Mejia ] * Improve each packages' long description. * Refresh all patches. [ Samuel Thibault ] * Skip libacl1-dev build dependency on hurd (Closes: #645403) [ Andreas Henriksson ] * Add 0009-Patch-from-upstream-rev-3751.patch (Closes: #641265) + Thanks to Michael Cree for figuring out the details. -- Andres Mejia Sun, 11 Dec 2011 21:55:59 -0500 libarchive (2.8.5-3) unstable; urgency=low * Fix upgrade breakage because of manpages being moved from libarchive1 to libarchive-dev. (Closes: #641978) * Make short descriptions for packages unique. * Explicitly set config options to be used during builds. -- Andres Mejia Sun, 18 Sep 2011 10:25:34 -0400 libarchive (2.8.5-2) unstable; urgency=low * Add gbp.conf to enable pristine-tar to true by default. * Add myself to uploaders field. * Add default options to fail on any upstream changes during a build. * Bump Standards-Version to 3.9.2. * Remove duplicate "Section" field. * Remove unnecessary use of *.dirs dh files. * Remove unneeded build-deps. * Provide patch that implements changes made after running autoreconf -vif. * Remove generic comments from debian/rules. * Support parallel builds. * Remove commented lines from install file. * Add docs to all packages except the shared library package. * Remove unneeded use of 'debian/tmp' in path for install files. * Provide different mechanism to install symlink for libarchive1 package. * Move all manpages for libarchive1 to libarchive-dev. * Move libarchive-dev control stanza up. This will make libarchive-dev the default package for installing files into, such as the README.Debian. * Convert libarchive into multiarch library package. * Update Vcs-* entries. -- Andres Mejia Sat, 17 Sep 2011 18:50:11 -0400 libarchive (2.8.5-1) unstable; urgency=low * Add 0010-Patch-from-upstream-rev-2811.patch * Drop "update-patch-series" target from debian/rules * Convert package to dh7 * Imported Upstream version 2.8.5 (Closes: #640524) * Rebase patch queue and drop patches merged upstream - dropped 0003-Patch-from-upstream-rev-2516.patch - dropped 0010-Patch-from-upstream-rev-2811.patch -- Andreas Henriksson Mon, 05 Sep 2011 17:35:36 +0200 libarchive (2.8.4-2) unstable; urgency=low * update-patch-series: + replace local patch with upstream commit. (Rebase patches branch to drop commit/patch "0007-Ignore-ENOSYS-error-when-sett...", in favor of upstream revision 2537 added as "0007-Patch-from-upstream-rev-2537.patch") + add 0008-Patch-from-upstream-rev-2888.patch (Closes: #610079) + add 0009-Patch-from-upstream-rev-2940.patch (Closes: #610783) -- Andreas Henriksson Tue, 09 Aug 2011 13:39:10 +0200 libarchive (2.8.4-1) unstable; urgency=low * Update debian/watch for new code.google.com layout. * update patch series: + added 0003-Patch-from-upstream-rev-2516.patch - Compatibility with WinISO generated iso files (Closes: #587513) + added 0004-Patch-from-upstream-rev-2514.patch + added 0005-Patch-from-upstream-rev-2520.patch - Enable version stripping code in iso9660/joliet (Closes: #587316) * Imported Upstream version 2.8.4 * update-patch-series: + added 0006-Patch-from-upstream-rev-2521.patch + added 0007-Ignore-ENOSYS-error-when-sett... (Closes: #588925) - Big thanks to Modestas Vainius for awesome debugging! -- Andreas Henriksson Thu, 15 Jul 2010 14:45:06 +0200 libarchive (2.8.3-1) unstable; urgency=low * Imported Upstream version 2.8.3 * update-patch-series: 0001-Clear-archive_error_number-in-archiv... - gvfs has been fixed since, workaround not needed anymore. -- Andreas Henriksson Fri, 23 Apr 2010 13:25:33 +0200 libarchive (2.8.0-2) unstable; urgency=low * Clean up libarchive.la file. (Closes: #571468) - Thanks to Sune Vuorela for suggesting this fix. * Update patch series: + added two patches matching revision 1990, 1991 from upstream regarding PATH_MAX hopefully fixing build on Hurd. -- Andreas Henriksson Thu, 25 Feb 2010 22:31:13 +0100 libarchive (2.8.0-1) unstable; urgency=low * Set myself as maintainer (Closes: #570539). + co-maintainers welcome! * Imported Upstream version 2.8.0 (Closes: #559158) * Drop debian revision in symbols file. * Updated symbols for 2.8 * Update rules for new build directory (config.aux -> build/autoconf) * Replace ${Source-Version} with ${source:Version} in control file. * Drop debian/shlibs.local.ex * Bump debhelper compatibility level to 5. * Stop trying to install non-existant usr/share/pkgconfig * Update Vcs fields to point to new collab-maint repository. * Update debian/copyright * Bump Standards-Version to 3.8.4 * Add update-patch-series target in debian/rules. * Added patch to fix gvfsd-archive problems: + 0001-Clear-archive_error_number-in-archive_clear_error.patch (from http://bugs.gentoo.org/show_bug.cgi?id=289260#c1 ) * Switch to dpkg-source 3.0 (quilt) format * Split Build-Depends on multiple lines. * Add liblzma-dev to Build-Depends for lzma support. * Add Build-Depends on libxml2-dev for xar support. * Explicitly give --without-openssl to configure. -- Andreas Henriksson Tue, 23 Feb 2010 20:50:25 +0100 libarchive (2.6.2-2) unstable; urgency=low * Orphaning the package; set maintainer to QA group. -- John Goerzen Fri, 19 Feb 2010 11:23:14 -0600 libarchive (2.6.2-1) unstable; urgency=low * New Upstream Version. Closes: #516577. * Update watch file to new homepage. Closes: #517398. -- John Goerzen Thu, 12 Mar 2009 09:32:31 -0500 libarchive (2.6.1-1) unstable; urgency=low * New Upstream Version * Update homepage. Closes: #514835. * Clean up Debian rules. Patch partially from Bernhard R. Link. Closes: #480495. -- John Goerzen Thu, 19 Feb 2009 09:28:57 -0600 libarchive (2.4.17-2) unstable; urgency=high [ John Goerzen ] * Ignore failures in test suite due to bugs in the testsuite that were turning into FTBFS bugs. Closes: #474400. * Added README.Debian documenting need for largefile suport in sources. Mostly used suggested text found in #479728. Closes: #479728. [ Bernhard R. Link ] * Added symbols file for libarchive. Closes: #476516. -- John Goerzen Thu, 05 Jun 2008 15:42:57 -0500 libarchive (2.4.17-1) unstable; urgency=high * New Upstream Version * This upstream version corrected several problems with the testsuite. Therefore, we can now run test suite after build. Closes: #473221. * uudecode is now used as part of the build. Added build-dep on sharutils. Fixes FTBFS. Closes: #473266. -- John Goerzen Thu, 03 Apr 2008 09:25:04 -0500 libarchive (2.4.14-1) unstable; urgency=high * New upstream release. Closes: #465061, #448292. #465061 is grave bug, so setting urgency high. * Added Vcs-* and Homepage lines to debian/control -- John Goerzen Sat, 29 Mar 2008 10:14:21 -0500 libarchive (2.4.11-1) unstable; urgency=low * New upstream version. * Move bsdtar to section utils. Closes: #460988. * Added bsdcpio package due to new upstream cpio command. -- John Goerzen Mon, 21 Jan 2008 10:02:29 -0600 libarchive (2.2.4-1) unstable; urgency=high * New upstream version with security fixes. Closes: #432924. Fixes: CVE-2007-3641, CVE-2007-3644, CVE-2007-3645 -- John Goerzen Fri, 13 Jul 2007 08:14:00 -0500 libarchive (2.2.3-1) unstable; urgency=low * New upstream version. -- John Goerzen Wed, 06 Jun 2007 03:36:35 -0500 libarchive (2.0.25-3) unstable; urgency=low * SONAME should not be tied to the tarball version string (Closes: #418637) Provide libarchive.so.1 as a backwards-compatible symlink to libarchive.so.2, reverting the package name to libarchive1. Patch from Neil Williams. -- John Goerzen Mon, 16 Apr 2007 13:50:29 +0100 libarchive (2.0.25-2) unstable; urgency=low * Remove build-dep on linux-kernel-headers for compatibility with BSD ports. Closes: #377480. -- John Goerzen Tue, 13 Mar 2007 20:03:37 -0500 libarchive (2.0.25-1) unstable; urgency=low * New upstream version * Remove unnecessary dep on libarchive1. Closes: #396756. * Bump standards-version * Rename libarchive1 to libarchive2 to match new soname. -- John Goerzen Tue, 13 Mar 2007 07:03:53 -0500 libarchive (1.3.1-1) unstable; urgency=high * New upstream release. * Applied FreeBSD patch for potential DoS. This is CVS-2006-5680, FreeBSD SA-06:24. -- John Goerzen Mon, 18 Dec 2006 05:51:08 -0600 libarchive (1.2.53-2) unstable; urgency=low * Added build-dep on bison. Closes: #374200. -- John Goerzen Sat, 17 Jun 2006 17:24:44 -0500 libarchive (1.2.53-1) unstable; urgency=low * New upstream version. * The bsdtar program has been integrated into the libarchive source package upstream. This package, therefore, now generates the bsdtar binary package. -- John Goerzen Sat, 17 Jun 2006 10:44:05 -0500 libarchive (1.02.036-2) unstable; urgency=low * Added conflict on old libarchive-doc package. This package never existed in testing or stable, so this conflict can be removed before long. -- John Goerzen Tue, 18 Oct 2005 11:02:06 -0500 libarchive (1.02.036-1) unstable; urgency=low * New upstream version, now with support for building as a .so. * Added build-dep on libattr1-dev. * No more libarchive-doc; its files now live in libarchive1. * Thanks to Bernhard R. Link for ideas for this package. -- John Goerzen Mon, 17 Oct 2005 10:27:30 -0500 libarchive (1.02.034-2) unstable; urgency=low * Split off manpages into separate package libarchive-doc. The bsdtar manpages point readers to these. -- John Goerzen Tue, 11 Oct 2005 05:36:28 -0500 libarchive (1.02.034-1) unstable; urgency=low * Initial release Closes: #333222. -- John Goerzen Mon, 10 Oct 2005 19:24:56 -0500 debian/bsdtar.install0000664000000000000000000000001712150214725012034 0ustar usr/bin/bsdtar