diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..28c8fa4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/libarchive-3.1.2.tar.gz
diff --git a/.libarchive.metadata b/.libarchive.metadata
new file mode 100644
index 0000000..158fc8e
--- /dev/null
+++ b/.libarchive.metadata
@@ -0,0 +1 @@
+6a991777ecb0f890be931cec4aec856d1a195489 SOURCES/libarchive-3.1.2.tar.gz
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8916-CVE-2015-8917.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8916-CVE-2015-8917.patch
new file mode 100644
index 0000000..9b6fc9e
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8916-CVE-2015-8917.patch
@@ -0,0 +1,35 @@
+From b2e2abbb13ddcd962470cc1adb43b085f6e407a4 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(+)
+
+diff --git a/tar/read.c b/tar/read.c
+index 8267b70..430cff0 100644
+--- a/tar/read.c
++++ b/tar/read.c
+@@ -264,6 +264,12 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
+ 		}
+ 		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);
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8919.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8919.patch
new file mode 100644
index 0000000..747a75d
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8919.patch
@@ -0,0 +1,37 @@
+From e8a2e4d2e6b450a239bb8f9d74239fa434bf7d35 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c
+index 572686a..f8e01af 100644
+--- a/libarchive/archive_read_support_format_lha.c
++++ b/libarchive/archive_read_support_format_lha.c
+@@ -1194,13 +1194,15 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
+ 				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);
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8920.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8920.patch
new file mode 100644
index 0000000..6bf2db3
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8920.patch
@@ -0,0 +1,87 @@
+From 97f964e3e0ce3ae34bfb4c366a37ba7c0d9610a6 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c
+index 82756c9..4b5b66b 100644
+--- a/libarchive/archive_read_support_format_ar.c
++++ b/libarchive/archive_read_support_format_ar.c
+@@ -180,7 +180,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ 	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. */
+@@ -239,8 +239,15 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ 	 * 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.
+@@ -262,12 +269,12 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ 		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. */
+@@ -311,11 +318,11 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ 		 */
+ 		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]);
+@@ -573,7 +580,7 @@ bad_string_table:
+ 	    "Invalid string table");
+ 	free(ar->strtab);
+ 	ar->strtab = NULL;
+-	return (ARCHIVE_WARN);
++	return (ARCHIVE_FATAL);
+ }
+ 
+ static uint64_t
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8921.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8921.patch
new file mode 100644
index 0000000..4d74549
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8921.patch
@@ -0,0 +1,76 @@
+From 6c2128928b93902d4af154a954ffa383591feba4 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sat, 7 Feb 2015 12:59:39 -0800
+Subject: [PATCH] Issue 404: Read past end of string parsing fflags
+
+--
+
+Correct the spelling of 'wcscmp'.
+
+--
+
+A correct fix for Issue 404: Read past end of string parsing fflags
+
+The previous fix actually broke the fflag parsing.  We
+cannot use strcmp() here because we're comparing a null-terminated
+string to a part of another string.
+
+This fix explicitly tracks the various string lengths and
+checks that they match before calling memcmp() or wmemcmp().
+That avoids any buffer overrun without breaking the parser.
+
+--
+Generated from commits: 1cbc76faff 05a875fdb8 90632371f
+---
+ libarchive/archive_entry.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c
+index 7958a17..787d281 100644
+--- a/libarchive/archive_entry.c
++++ b/libarchive/archive_entry.c
+@@ -1744,14 +1744,17 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
+ 		while (*end != '\0'  &&  *end != '\t'  &&
+ 		    *end != ' '  &&  *end != ',')
+ 			end++;
++		size_t 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;
+@@ -1808,14 +1811,17 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
+ 		while (*end != L'\0'  &&  *end != L'\t'  &&
+ 		    *end != L' '  &&  *end != L',')
+ 			end++;
++		size_t 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;
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8922.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8922.patch
new file mode 100644
index 0000000..bfb684a
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8922.patch
@@ -0,0 +1,170 @@
+From d094dc02905605ca514baf87855f026b9bf52f1f Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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
+
+diff --git a/Makefile.am b/Makefile.am
+index d6e40a2..f6e1e20 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -372,6 +372,7 @@ libarchive_test_SOURCES=					\
+ 	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		\
+@@ -599,6 +600,8 @@ libarchive_test_EXTRA_DIST=\
+ 	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			\
+diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
+index 194b8d5..e490c00 100644
+--- a/libarchive/archive_read_support_format_7zip.c
++++ b/libarchive/archive_read_support_format_7zip.c
+@@ -1940,7 +1940,16 @@ read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
+ 			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)
+diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
+index 6ac850d..08770d9 100644
+--- a/libarchive/test/CMakeLists.txt
++++ b/libarchive/test/CMakeLists.txt
+@@ -87,6 +87,7 @@ IF(ENABLE_TEST)
+     test_read_filter_program_signature.c
+     test_read_filter_uudecode.c
+     test_read_format_7zip.c
++    test_read_format_7zip_malformed.c
+     test_read_format_ar.c
+     test_read_format_cab.c
+     test_read_format_cab_filename.c
+diff --git a/libarchive/test/test_read_format_7zip_malformed.7z.uu b/libarchive/test/test_read_format_7zip_malformed.7z.uu
+new file mode 100644
+index 0000000..179f633
+--- /dev/null
++++ b/libarchive/test/test_read_format_7zip_malformed.7z.uu
+@@ -0,0 +1,5 @@
++begin 644 test_read_format_7zip_malformed.7z
++M-WJ\KR<<,#"@P/<&!P````````!(`````````&:^$Y<P,#`P,#`P`00&``$)
++'!P`'"S`P#```
++`
++end
+diff --git a/libarchive/test/test_read_format_7zip_malformed.c b/libarchive/test/test_read_format_7zip_malformed.c
+new file mode 100644
+index 0000000..4ca6f09
+--- /dev/null
++++ b/libarchive/test/test_read_format_7zip_malformed.c
+@@ -0,0 +1,67 @@
++/*-
++ * 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_7zip_malformed.7z";
++	struct archive *a;
++	struct archive_entry *ae;
++
++	extract_reference_file(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, archive_read_open_filename(a, refname, 10240));
++	assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
++	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
++}
++
++static void
++test_malformed2(void)
++{
++	const char *refname = "test_read_format_7zip_malformed2.7z";
++	struct archive *a;
++	struct archive_entry *ae;
++
++	extract_reference_file(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, archive_read_open_filename(a, refname, 10240));
++	assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae));
++	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
++}
++
++DEFINE_TEST(test_read_format_7zip_malformed)
++{
++	test_malformed1();
++	test_malformed2();
++}
+diff --git a/libarchive/test/test_read_format_7zip_malformed2.7z.uu b/libarchive/test/test_read_format_7zip_malformed2.7z.uu
+new file mode 100644
+index 0000000..e629a78
+--- /dev/null
++++ b/libarchive/test/test_read_format_7zip_malformed2.7z.uu
+@@ -0,0 +1,5 @@
++begin 644 test_read_format_7zip_malformed2.7z
++M-WJ\KR<<,#"@P/<&!P````````!(`````````&:^$Y<P,#`P,#`P`00&``$)
++(!P`'"S`!#`P`
++`
++end
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8923.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8923.patch
new file mode 100644
index 0000000..ca2e756
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8923.patch
@@ -0,0 +1,147 @@
+From 9e0689cff30f64defb2691003143a7ad3126c74a Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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.
+
+---
+diff --git a/Makefile.am b/Makefile.am
+index f6e1e20..fb90b9c 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -428,6 +428,7 @@ libarchive_test_SOURCES=					\
+ 	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		\
+@@ -685,6 +686,7 @@ libarchive_test_EXTRA_DIST=\
+ 	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			\
+diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
+index 450a6f7..1aed84a 100644
+--- a/libarchive/archive_read_support_format_zip.c
++++ b/libarchive/archive_read_support_format_zip.c
+@@ -1701,7 +1701,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
+ 			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(
+@@ -1713,7 +1713,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
+ 				}
+ 				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(
+diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
+index 08770d9..2dc1740 100644
+--- a/libarchive/test/CMakeLists.txt
++++ b/libarchive/test/CMakeLists.txt
+@@ -143,6 +143,7 @@ IF(ENABLE_TEST)
+     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
+diff --git a/libarchive/test/test_read_format_zip_malformed.c b/libarchive/test/test_read_format_zip_malformed.c
+new file mode 100644
+index 0000000..2327d91
+--- /dev/null
++++ b/libarchive/test/test_read_format_zip_malformed.c
+@@ -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();
++}
+diff --git a/libarchive/test/test_read_format_zip_malformed1.zip.uu b/libarchive/test/test_read_format_zip_malformed1.zip.uu
+new file mode 100644
+index 0000000..cbd21a8
+--- /dev/null
++++ b/libarchive/test/test_read_format_zip_malformed1.zip.uu
+@@ -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
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8924.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8924.patch
new file mode 100644
index 0000000..ae452be
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8924.patch
@@ -0,0 +1,66 @@
+From bb9b157146a62e655fb369b32684398c949fa1b1 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
+index 37399a0..1e78093 100644
+--- a/libarchive/archive_read_support_format_tar.c
++++ b/libarchive/archive_read_support_format_tar.c
+@@ -456,6 +456,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
+ 	static int default_dev;
+ 	struct tar *tar;
+ 	const char *p;
++	const wchar_t *wp;
+ 	int r;
+ 	size_t l, unconsumed = 0;
+ 
+@@ -506,27 +507,22 @@ archive_read_format_tar_read_header(struct archive_read *a,
+ 		}
+ 	}
+ 
+-	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);
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8925.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8925.patch
new file mode 100644
index 0000000..841b90c
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8925.patch
@@ -0,0 +1,166 @@
+From 1e18cbb71515a22b2a6f1eb4aaadea461929b834 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
+index c4e7021..397bfee 100644
+--- a/libarchive/archive_read_support_format_mtree.c
++++ b/libarchive/archive_read_support_format_mtree.c
+@@ -1661,6 +1661,10 @@ parse_escapes(char *src, struct mtree_entry *mentry)
+ 				c = '\v';
+ 				++src;
+ 				break;
++			case '\\':
++				c = '\\';
++				++src;
++				break;
+ 			}
+ 		}
+ 		*dest++ = c;
+@@ -1804,8 +1808,7 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
+ 	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 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
+ 			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 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
+ 			    "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;
+ 	}
+diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c
+index efedc41..85a0e2e 100644
+--- a/libarchive/test/test_read_format_mtree.c
++++ b/libarchive/test/test_read_format_mtree.c
+@@ -110,6 +110,10 @@ test_read_format_mtree1(void)
+ 	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 @@ test_read_format_mtree1(void)
+ 	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));
+ }
+diff --git a/libarchive/test/test_read_format_mtree.mtree.uu b/libarchive/test/test_read_format_mtree.mtree.uu
+index a0dff18..f1c9d60 100644
+--- a/libarchive/test/test_read_format_mtree.mtree.uu
++++ b/libarchive/test/test_read_format_mtree.mtree.uu
+@@ -5,14 +5,16 @@ M92!U:60],3@*("XN"F9I;&5<,#0P=VET:%PP-#!S<&%C92!T>7!E/69I;&4*
+ M9&ER,B!T>7!E/61I<@H@9&ER,V$@='EP93UD:7(*("!I;F1I<C-A('1Y<&4]
+ M9FEL90ID:7(R+V9U;&QI;F1I<C(@='EP93UF:6QE(&UO9&4],#<W-PH@("XN
+ M"B!I;F1I<C(@='EP93UF:6QE"B!D:7(S8B!T>7!E/61I<@H@(&EN9&ER,V(@
+-M='EP93UF:6QE"B`@+BX*("XN"FYO=&EN9&ER('1Y<&4]9FEL90ID:7(R+V9U
+-M;&QI;F1I<C(@;6]D93TP-C0T"F1I<C(O96UP='EF:6QE('1Y<&4]9FEL92!S
+-M:7IE/3!X,`ID:7(R+W-M86QL9FEL92!T>7!E/69I;&4@<VEZ93TP,#`P,#`P
+-M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#$*9&ER,B]T;V]S;6%L;&9I;&4@='EP
+-M93UF:6QE('-I>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-#<W-3@P.`ID:7(R+W1O;V]L9&9I
+-H;&4@='EP93UF:6QE('1I;64]+3DR,C,S-S(P,S8X-30W-S4X,#D*"@``
++M='EP93UF:6QE"B`@9FEL96YA;65<7'=I=&A<"E]E<V-<8EQT7&9A<&5S('1Y
++M<&4]9FEL92!M;V1E/3`T-#0@<VEZ93TP"B`@+BX*("XN"FYO=&EN9&ER('1Y
++M<&4]9FEL90ID:7(R+V9U;&QI;F1I<C(@;6]D93TP-C0T"F1I<C(O96UP='EF
++M:6QE('1Y<&4]9FEL92!S:7IE/3!X,`ID:7(R+W-M86QL9FEL92!T>7!E/69I
++M;&4@<VEZ93TP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#$*9&ER,B]T
++M;V]S;6%L;&9I;&4@='EP93UF:6QE('-I>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-#<W-3@P
++M.`ID:7(R+W1O;V]L9&9I;&4@='EP93UF:6QE('1I;64]+3DR,C,S-S(P,S8X
++*-30W-S4X,#D*"@``
+ `
+ end
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8926.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8926.patch
new file mode 100644
index 0000000..de358ba
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8926.patch
@@ -0,0 +1,39 @@
+From aab73938f8914f0def6cdd5d5be3f142ae7c77f6 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
+index 3e7412f..ee8ce53 100644
+--- a/libarchive/archive_read_support_format_rar.c
++++ b/libarchive/archive_read_support_format_rar.c
+@@ -1002,8 +1002,8 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
+       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)
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8928.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8928.patch
new file mode 100644
index 0000000..a4c8244
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8928.patch
@@ -0,0 +1,106 @@
+From f667f381486371ccb19f2b1e7307a695cf3a5279 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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 | 53 ++++++++++++++------------
+ 1 file changed, 29 insertions(+), 24 deletions(-)
+
+diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
+index 397bfee..a672cb3 100644
+--- a/libarchive/archive_read_support_format_mtree.c
++++ b/libarchive/archive_read_support_format_mtree.c
+@@ -826,8 +826,8 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
+ 	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 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
+ 	*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) {
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8930.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8930.patch
new file mode 100644
index 0000000..e7d44ab
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8930.patch
@@ -0,0 +1,129 @@
+From 139c528ab8016711b6b59a4460afd0d6b236beb5 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sat, 11 Apr 2015 22:44:12 -0700
+Subject: [PATCH] This is a combination of 2 commits.
+
+==  The first commit's message is: ==
+
+Issue #522: Dir loop in malformed ISO causes segfault
+
+Github Issue #522 revealed that we could blow the stack
+when recursing to assemble ISO paths.  I saw this happen
+at 130,000 dir levels.  This patch addresses this by limiting
+the directory recursion to 1,000 elements.
+
+TODO:  It would be even better to track and detect the dir loop
+directly.
+
+== This is the 2nd commit message: ==
+
+Github Issue #522: Detect cycles in the ISO directory tree
+---
+ libarchive/archive_read_support_format_iso9660.c | 43 +++++++++++++++++++-----
+ 1 file changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
+index 47268a2..6934cee 100644
+--- a/libarchive/archive_read_support_format_iso9660.c
++++ b/libarchive/archive_read_support_format_iso9660.c
+@@ -387,7 +387,7 @@ static int	archive_read_format_iso9660_read_data(struct archive_read *,
+ 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
+@@ -1225,6 +1225,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
+ 			archive_set_error(&a->archive,
+ 			    ARCHIVE_ERRNO_FILE_FORMAT,
+ 			    "Pathname is too long");
++			return (ARCHIVE_FATAL);
+ 		}
+ 
+ 		r = archive_entry_copy_pathname_l(entry,
+@@ -1247,9 +1248,16 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
+ 			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;
+@@ -1744,12 +1752,12 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
+     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;
+ 
+@@ -1793,6 +1801,16 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
+ 		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) {
+@@ -1801,7 +1819,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
+ 		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;
+@@ -3169,10 +3187,17 @@ time_from_tm(struct tm *t)
+ }
+ 
+ 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)
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8931.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8931.patch
new file mode 100644
index 0000000..4c04473
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8931.patch
@@ -0,0 +1,94 @@
+From 11f6da24b13840397fee87445859d7f2a2ac02f8 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sat, 16 May 2015 12:16:28 -0700
+Subject: [PATCH] This is a combination of 2 commits. == The first commit's
+ message is: ==
+
+Issue #539:  Try a different way to compute max/min time_t values.
+
+== This is the 2nd commit message: ==
+
+Don't try to be smart about probing the min/max tim_t values.
+Just assume that a signed time_t is really a 64-bit or 32-bit integer.
+---
+ libarchive/archive_read_support_format_mtree.c | 47 ++++++++++++++------------
+ 1 file changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
+index 64d5e67..3abe198 100644
+--- a/libarchive/archive_read_support_format_mtree.c
++++ b/libarchive/archive_read_support_format_mtree.c
+@@ -139,16 +139,22 @@ get_time_t_max(void)
+ #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
+ }
+ 
+@@ -158,20 +164,17 @@ get_time_t_min(void)
+ #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
+ }
+ 
+@@ -1562,7 +1565,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
+ 			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);
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8932.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8932.patch
new file mode 100644
index 0000000..a4b3f85
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8932.patch
@@ -0,0 +1,178 @@
+From 9ef77b3d5e04de8323bdc61c1cb7ea77613e4a38 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sat, 8 Aug 2015 21:47:43 -0700
+Subject: [PATCH] This is a combination of 2 commits. == The first commit's
+ message is: ==
+
+Issue 547:  problems with compress bidder
+
+The code previously was not very careful about verifying the
+compression parameters.  This led to cases where it failed to
+reject invalid compressed data at the beginning.  The invalid
+left shift was one symptom of this.
+
+The code is now more careful:  It verifies that the compression
+parameter byte exists and verifies that the maximum code size
+is <= 16 bits.
+
+This also includes some new tests to verify that truncated or
+otherwise invalid compressed data is rejected.
+
+== This is the 2nd commit message: ==
+
+add missing tests to automake
+---
+ Makefile.am                                       |  1 +
+ libarchive/archive_read_support_filter_compress.c | 21 ++++--
+ libarchive/test/test_read_filter_compress.c       | 80 +++++++++++++++++++++++
+ 3 files changed, 96 insertions(+), 6 deletions(-)
+ create mode 100644 libarchive/test/test_read_filter_compress.c
+
+diff --git a/Makefile.am b/Makefile.am
+index fb90b9c..e088b75 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -364,6 +364,7 @@ libarchive_test_SOURCES=					\
+ 	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			\
+diff --git a/libarchive/archive_read_support_filter_compress.c b/libarchive/archive_read_support_filter_compress.c
+index 3f5d1f3..6fa9993 100644
+--- a/libarchive/archive_read_support_filter_compress.c
++++ b/libarchive/archive_read_support_filter_compress.c
+@@ -185,19 +185,22 @@ compress_bidder_bid(struct archive_read_filter_bidder *self,
+ 
+ 	(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 @@ compress_bidder_init(struct archive_read_filter *self)
+ 	(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;
+diff --git a/libarchive/test/test_read_filter_compress.c b/libarchive/test/test_read_filter_compress.c
+new file mode 100644
+index 0000000..03a1d5f
+--- /dev/null
++++ b/libarchive/test/test_read_filter_compress.c
+@@ -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)
++{
++	const 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)
++{
++	const 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)
++{
++	const 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));
++}
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2015-8934.patch b/SOURCES/libarchive-3.1.2-CVE-2015-8934.patch
new file mode 100644
index 0000000..9babdea
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2015-8934.patch
@@ -0,0 +1,145 @@
+From 470ceb47fe072d10c4b5d02dba3a8b7b3ce731e5 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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
+
+diff --git a/Makefile.am b/Makefile.am
+index e088b75..40ac1d1 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -414,6 +414,7 @@ libarchive_test_SOURCES=					\
+ 	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	\
+diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
+index 94cd108..c06a32b 100644
+--- a/libarchive/archive_read_support_format_rar.c
++++ b/libarchive/archive_read_support_format_rar.c
+@@ -2798,11 +2798,10 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
+   }
+ 
+   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 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
+              &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)
+diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
+index 2dc1740..3751da9 100644
+--- a/libarchive/test/CMakeLists.txt
++++ b/libarchive/test/CMakeLists.txt
+@@ -128,6 +128,7 @@ IF(ENABLE_TEST)
+     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
+diff --git a/libarchive/test/test_read_format_rar_invalid1.c b/libarchive/test/test_read_format_rar_invalid1.c
+new file mode 100644
+index 0000000..61dea16
+--- /dev/null
++++ b/libarchive/test/test_read_format_rar_invalid1.c
+@@ -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));
++}
+diff --git a/libarchive/test/test_read_format_rar_invalid1.rar.uu b/libarchive/test/test_read_format_rar_invalid1.rar.uu
+new file mode 100644
+index 0000000..2380399
+--- /dev/null
++++ b/libarchive/test/test_read_format_rar_invalid1.rar.uu
+@@ -0,0 +1,5 @@
++begin 644 test_read_format_rar_invalid1.rar
++M4F%R(1H'`,^0<P``#0````````"9SG0@D"8`#`````,````#+7,'\(^>B$4=
++2,P0`I($``'1E<W0`P/\````)
++`
++end
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-1541.patch b/SOURCES/libarchive-3.1.2-CVE-2016-1541.patch
new file mode 100644
index 0000000..7786dc8
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-1541.patch
@@ -0,0 +1,70 @@
+From 1966a9c18521a15d79f64fe893040e3fdb5a3790 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(+)
+
+diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
+index 1aed84a..fa3db11 100644
+--- a/libarchive/archive_read_support_format_zip.c
++++ b/libarchive/archive_read_support_format_zip.c
+@@ -560,6 +560,11 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ 
+ 	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 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ 		    (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 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ 			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;
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-4300.patch b/SOURCES/libarchive-3.1.2-CVE-2016-4300.patch
new file mode 100644
index 0000000..34bfd05
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-4300.patch
@@ -0,0 +1,32 @@
+From f084b0568ac2845f12a9a34e0636811d49d6a2a8 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sun, 19 Jun 2016 14:14:09 -0700
+Subject: [PATCH] Issue #718: Fix TALOS-CAN-152
+
+If a 7-Zip archive declares a rediculously large number of substreams,
+it can overflow an internal counter, leading a subsequent memory
+allocation to be too small for the substream data.
+
+Thanks to the Open Source and Threat Intelligence project at Cisco
+for reporting this issue.
+---
+ libarchive/archive_read_support_format_7zip.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
+index e490c00..8ae8443 100644
+--- a/libarchive/archive_read_support_format_7zip.c
++++ b/libarchive/archive_read_support_format_7zip.c
+@@ -2054,6 +2054,9 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
+ 				return (-1);
+ 			if (1000000 < f[i].numUnpackStreams)
+ 				return (-1);
++			if (unpack_streams > SIZE_MAX - 1000000) {
++				return (-1);
++			}
+ 			unpack_streams += (size_t)f[i].numUnpackStreams;
+ 		}
+ 		if ((p = header_bytes(a, 1)) == NULL)
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-4302.patch b/SOURCES/libarchive-3.1.2-CVE-2016-4302.patch
new file mode 100644
index 0000000..d20fefc
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-4302.patch
@@ -0,0 +1,35 @@
+From 05caadc7eedbef471ac9610809ba683f0c698700 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sun, 19 Jun 2016 14:21:42 -0700
+Subject: [PATCH] Issue 719:  Fix for TALOS-CAN-154
+
+A RAR file with an invalid zero dictionary size was not being
+rejected, leading to a zero-sized allocation for the dictionary
+storage which was then overwritten during the dictionary initialization.
+
+Thanks to the Open Source and Threat Intelligence project at Cisco for
+reporting this.
+---
+ libarchive/archive_read_support_format_rar.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
+index 6450aac..6c49f1a 100644
+--- a/libarchive/archive_read_support_format_rar.c
++++ b/libarchive/archive_read_support_format_rar.c
+@@ -2127,6 +2127,12 @@ parse_codes(struct archive_read *a)
+       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))
+       {
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-4809.patch b/SOURCES/libarchive-3.1.2-CVE-2016-4809.patch
new file mode 100644
index 0000000..22d7489
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-4809.patch
@@ -0,0 +1,28 @@
+From fd7e0c02e272913a0a8b6d492c7260dfca0b1408 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(+)
+
+diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c
+index c2ca85b..b09db0e 100644
+--- a/libarchive/archive_read_support_format_cpio.c
++++ b/libarchive/archive_read_support_format_cpio.c
+@@ -401,6 +401,11 @@ archive_read_format_cpio_read_header(struct archive_read *a,
+ 
+ 	/* 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)
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-5418-variation.patch b/SOURCES/libarchive-3.1.2-CVE-2016-5418-variation.patch
new file mode 100644
index 0000000..43f6ac8
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-5418-variation.patch
@@ -0,0 +1,150 @@
+commit 3c378bb5e4ea8d4c9a5345083f278882322f9c9b
+Author: Doran Moppert <dmoppert@redhat.com>
+Date:   Fri Aug 12 13:58:57 2016 +0930
+
+    Fix for hardlinks with .. in target path
+     - factor cleanup_pathname into cleanup_pathname_fsobj
+     - rename check_path_for_symlinks to check_path_fsobj for consistency
+
+diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
+index 66fc0f5..37261a5 100644
+--- a/libarchive/archive_write_disk_posix.c
++++ b/libarchive/archive_write_disk_posix.c
+@@ -326,13 +326,14 @@ struct archive_write_disk {
+ 
+ #define HFS_BLOCKS(s)	((s) >> 12)
+ 
+-static int check_path_for_symlinks(char *path, int *error_number, struct archive_string *error_string, int flags);
++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 *);
+@@ -1997,7 +1998,7 @@ create_filesystem_object(struct archive_write_disk *a)
+ 	const char *linkname;
+ 	mode_t final_mode, mode;
+ 	int r;
+-	/* these for check_path_for_symlinks */
++	/* these for check_symlinks_fsobj */
+ 	char *linkname_copy;	/* non-const copy of linkname */
+ 	struct archive_string error_string;
+ 	int error_number;
+@@ -2014,13 +2015,22 @@ create_filesystem_object(struct archive_write_disk *a)
+ 		if (linkname_copy == NULL) {
+ 		    return (EPERM);
+ 		}
+-		r = check_path_for_symlinks(linkname_copy, &error_number, &error_string, a->flags);
+-		free(linkname_copy);
++		/* 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
+@@ -2365,7 +2375,8 @@ current_fixup(struct archive_write_disk *a, const char *pathname)
+  * 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_path_for_symlinks(char *path, int *error_number, struct archive_string *error_string, int flags)
++static int
++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. */
+@@ -2558,7 +2569,7 @@ check_symlinks(struct archive_write_disk *a)
+ 	int error_number;
+ 	int rc;
+ 	archive_string_init(&error_string);
+-	rc = check_path_for_symlinks(a->name, &error_number, &error_string, a->flags);
++	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);
+ 	}
+@@ -2640,15 +2651,17 @@ cleanup_pathname_win(struct archive_write_disk *a)
+  * set) any '..' in the path.
+  */
+ 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);
+ 	}
+ 
+@@ -2679,10 +2692,11 @@ cleanup_pathname(struct archive_write_disk *a)
+ 			} 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);
+ 					}
+ 				}
+@@ -2713,7 +2727,7 @@ cleanup_pathname(struct archive_write_disk *a)
+ 	 * 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 '/././././/./'.
+@@ -2728,6 +2742,21 @@ cleanup_pathname(struct archive_write_disk *a)
+ 	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.
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-5418.patch b/SOURCES/libarchive-3.1.2-CVE-2016-5418.patch
new file mode 100644
index 0000000..4b9cd7e
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-5418.patch
@@ -0,0 +1,324 @@
+diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
+index bbd50a6..66fc0f5 100644
+--- a/libarchive/archive_write_disk_posix.c
++++ b/libarchive/archive_write_disk_posix.c
+@@ -326,6 +326,7 @@ struct archive_write_disk {
+ 
+ #define HFS_BLOCKS(s)	((s) >> 12)
+ 
++static int check_path_for_symlinks(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);
+@@ -1791,7 +1792,7 @@ edit_deep_directories(struct archive_write_disk *a)
+ 	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. */
+@@ -1801,7 +1802,7 @@ edit_deep_directories(struct archive_write_disk *a)
+ 		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 != '/')
+@@ -1996,6 +1997,10 @@ create_filesystem_object(struct archive_write_disk *a)
+ 	const char *linkname;
+ 	mode_t final_mode, mode;
+ 	int r;
++	/* these for check_path_for_symlinks */
++	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 +2009,18 @@ create_filesystem_object(struct archive_write_disk *a)
+ #if !HAVE_LINK
+ 		return (EPERM);
+ #else
++		archive_string_init(&error_string);
++		linkname_copy = strdup(linkname);
++		if (linkname_copy == NULL) {
++		    return (EPERM);
++		}
++		r = check_path_for_symlinks(linkname_copy, &error_number, &error_string, a->flags);
++		free(linkname_copy);
++		if (r != ARCHIVE_OK) {
++			archive_set_error(&a->archive, error_number, "%s", error_string.s);
++			/* EPERM is more appropriate than error_number for our callers */
++			return (EPERM);
++		}
+ 		r = link(linkname, a->name) ? errno : 0;
+ 		/*
+ 		 * New cpio and pax formats allow hardlink entries
+@@ -2343,99 +2360,214 @@ current_fixup(struct archive_write_disk *a, const char *pathname)
+  * recent paths.
+  */
+ /* TODO: Extend this to support symlinks on Windows Vista and later. */
+-static int
+-check_symlinks(struct archive_write_disk *a)
++
++/*
++ * 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_path_for_symlinks(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.
++	 *
++	 * 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
+ 	 */
+-	/* 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')) {
++	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? */
++
++	/* 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;
++			/* Treat any other error as fatal - best to be paranoid here */
++			if(error_number) *error_number = errno;
++			if(error_string)
++				archive_string_sprintf(error_string,
++					"Could not stat %s",
++					path);
++			res = (ARCHIVE_FATAL);
++			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.
+ 				 */
++				tail[0] = c;
++				/* FIXME:  not sure how important this is to restore
+ 				if (!S_ISLNK(a->mode)) {
+-					archive_set_error(&a->archive, 0,
+-					    "Removing symlink %s",
+-					    a->name);
++					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;
+ 			} 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;
+ 	}
+-	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 = 0;
++			if(error_string)
++				archive_string_sprintf(error_string,
++					"Cannot extract through symlink %s",
++					path);
++		}
++		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_path_for_symlinks(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 '/' .
diff --git a/SOURCES/libarchive-3.1.2-CVE-2016-5844.patch b/SOURCES/libarchive-3.1.2-CVE-2016-5844.patch
new file mode 100644
index 0000000..d769af5
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2016-5844.patch
@@ -0,0 +1,40 @@
+From 3ad08e01b4d253c66ae56414886089684155af22 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
+index 6934cee..f41ba38 100644
+--- a/libarchive/archive_read_support_format_iso9660.c
++++ b/libarchive/archive_read_support_format_iso9660.c
+@@ -1091,7 +1091,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
+ 		/* 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);
+@@ -1129,7 +1129,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
+ 	    && 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)
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2017-14503.patch b/SOURCES/libarchive-3.1.2-CVE-2017-14503.patch
new file mode 100644
index 0000000..deebbed
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2017-14503.patch
@@ -0,0 +1,29 @@
+From 2c8c83b9731ff822fad6cc8c670ea5519c366a14 Mon Sep 17 00:00:00 2001
+From: Joerg Sonnenberger <joerg@bec.de>
+Date: Thu, 19 Jul 2018 21:14:53 +0200
+Subject: [PATCH] Reject LHA archive entries with negative size.
+
+---
+ libarchive/archive_read_support_format_lha.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c
+index b8ef4ae1..95c99bb1 100644
+--- a/libarchive/archive_read_support_format_lha.c
++++ b/libarchive/archive_read_support_format_lha.c
+@@ -701,6 +701,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;
+ 
+-- 
+2.20.1
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2019-1000019.patch b/SOURCES/libarchive-3.1.2-CVE-2019-1000019.patch
new file mode 100644
index 0000000..f05595e
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2019-1000019.patch
@@ -0,0 +1,58 @@
+From 65a23f5dbee4497064e9bb467f81138a62b0dae1 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 1 Jan 2019 16:01:40 +1100
+Subject: [PATCH 2/2] 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(-)
+
+diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
+index bccbf896..b6d1505d 100644
+--- a/libarchive/archive_read_support_format_7zip.c
++++ b/libarchive/archive_read_support_format_7zip.c
+@@ -2964,13 +2964,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
+ 	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,
+-- 
+2.20.1
+
diff --git a/SOURCES/libarchive-3.1.2-CVE-2019-1000020.patch b/SOURCES/libarchive-3.1.2-CVE-2019-1000020.patch
new file mode 100644
index 0000000..b314520
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-CVE-2019-1000020.patch
@@ -0,0 +1,59 @@
+From 8312eaa576014cd9b965012af51bc1f967b12423 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 1 Jan 2019 17:10:49 +1100
+Subject: [PATCH 1/2] 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(-)
+
+diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
+index 28acfefb..bad8f1df 100644
+--- a/libarchive/archive_read_support_format_iso9660.c
++++ b/libarchive/archive_read_support_format_iso9660.c
+@@ -2102,6 +2102,7 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
+     const unsigned char *p, const unsigned char *end)
+ {
+ 	struct iso9660 *iso9660;
++	int entry_seen = 0;
+ 
+ 	iso9660 = (struct iso9660 *)(a->format->data);
+ 
+@@ -2257,8 +2258,16 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
+ 		}
+ 
+ 		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
+-- 
+2.20.1
+
diff --git a/SOURCES/libarchive-3.1.2-rhbz-1347085.patch b/SOURCES/libarchive-3.1.2-rhbz-1347085.patch
new file mode 100644
index 0000000..c60280b
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-rhbz-1347085.patch
@@ -0,0 +1,84 @@
+From 3014e19820ea53c15c90f9d447ca3e668a0b76c6 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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(-)
+
+diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
+index 4d832fb..cb3e54e 100644
+--- a/libarchive/archive_write_set_format_iso9660.c
++++ b/libarchive/archive_write_set_format_iso9660.c
+@@ -6225,7 +6225,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ 	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
+ 	};
+@@ -6239,7 +6239,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ 	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);
+ 
+@@ -6252,7 +6252,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ 		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);
+@@ -6285,7 +6285,7 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ 		/*
+ 		 * 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 &&
+@@ -6302,7 +6302,9 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ 
+ 		/* 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 "
+@@ -6314,11 +6316,11 @@ isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ 
+ 		/* 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;
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-rhbz-1347086.patch b/SOURCES/libarchive-3.1.2-rhbz-1347086.patch
new file mode 100644
index 0000000..a9abbd5
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-rhbz-1347086.patch
@@ -0,0 +1,163 @@
+From 6e06b1c89dd0d16f74894eac4cfc1327a06ee4a0 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+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
+
+diff --git a/Makefile.am b/Makefile.am
+index 3fa2d22..d6e40a2 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -432,6 +432,7 @@ libarchive_test_SOURCES=					\
+ 	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			\
+@@ -693,6 +694,7 @@ libarchive_test_EXTRA_DIST=\
+ 	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		\
+diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
+index 048c316..f8dde89 100644
+--- a/libarchive/archive_read.c
++++ b/libarchive/archive_read.c
+@@ -544,13 +544,13 @@ archive_read_open1(struct archive *_a)
+ 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 @@ choose_filters(struct archive_read *a)
+ 			return (ARCHIVE_FATAL);
+ 		}
+ 	}
++	archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
++	    "Input requires too many filters for decoding");
++	return (ARCHIVE_FATAL);
+ }
+ 
+ /*
+diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
+index d2eb2c2..6ac850d 100644
+--- a/libarchive/test/CMakeLists.txt
++++ b/libarchive/test/CMakeLists.txt
+@@ -147,6 +147,7 @@ IF(ENABLE_TEST)
+     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
+diff --git a/libarchive/test/test_read_too_many_filters.c b/libarchive/test/test_read_too_many_filters.c
+new file mode 100644
+index 0000000..37cab24
+--- /dev/null
++++ b/libarchive/test/test_read_too_many_filters.c
+@@ -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));
++}
+diff --git a/libarchive/test/test_read_too_many_filters.gz.uu b/libarchive/test/test_read_too_many_filters.gz.uu
+new file mode 100644
+index 0000000..6bf6614
+--- /dev/null
++++ b/libarchive/test/test_read_too_many_filters.gz.uu
+@@ -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
+-- 
+2.7.4
+
diff --git a/SOURCES/libarchive-3.1.2-testsuite.patch b/SOURCES/libarchive-3.1.2-testsuite.patch
new file mode 100644
index 0000000..8a9841c
--- /dev/null
+++ b/SOURCES/libarchive-3.1.2-testsuite.patch
@@ -0,0 +1,150 @@
+diff --git a/cpio/test/test_extract_cpio_lzo.c b/cpio/test/test_extract_cpio_lzo.c
+index f351ba7..99476af 100644
+--- a/cpio/test/test_extract_cpio_lzo.c
++++ b/cpio/test/test_extract_cpio_lzo.c
+@@ -27,7 +27,7 @@ __FBSDID("$FreeBSD$");
+ 
+ DEFINE_TEST(test_extract_cpio_lzo)
+ {
+-	const char *reffile = "test_extract.cpio.lrz";
++	const char *reffile = "test_extract.cpio.lzo";
+ 	int f;
+ 
+ 	extract_reference_file(reffile);
+diff --git a/libarchive/test/test_write_filter_lzop.c b/libarchive/test/test_write_filter_lzop.c
+index 9e840bd..a32932c 100644
+--- a/libarchive/test/test_write_filter_lzop.c
++++ b/libarchive/test/test_write_filter_lzop.c
+@@ -39,7 +39,7 @@ DEFINE_TEST(test_write_filter_lzop)
+ 	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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 
+ 	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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 	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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 	} 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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 	    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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 		    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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 	    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 @@ DEFINE_TEST(test_write_filter_lzop)
+ 	} 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)))
+diff --git a/tar/test/test_option_b.c b/tar/test/test_option_b.c
+index be2ae65..7164d4c 100644
+--- a/tar/test/test_option_b.c
++++ b/tar/test/test_option_b.c
+@@ -25,8 +25,14 @@
+ #include "test.h"
+ __FBSDID("$FreeBSD$");
+ 
++static char *ustar_opt = " --format=ustar";
++
+ DEFINE_TEST(test_option_b)
+ {
++	char *testprog_ustar = malloc(strlen(testprog) + strlen(ustar_opt) + 2);
++	strcpy(testprog_ustar, testprog);
++	strcat(testprog_ustar, ustar_opt);
++
+ 	assertMakeFile("file1", 0644, "file1");
+ 	if (systemf("cat file1 > test_cat.out 2> test_cat.err") != 0) {
+ 		skipping("Platform doesn't have cat");
+@@ -36,7 +42,7 @@ DEFINE_TEST(test_option_b)
+ 	/*
+ 	 * Bsdtar does not pad if the output is going directly to a disk file.
+ 	 */
+-	assertEqualInt(0, systemf("%s -cf archive1.tar file1 >test1.out 2>test1.err", testprog));
++	assertEqualInt(0, systemf("%s -cf archive1.tar file1 >test1.out 2>test1.err", testprog_ustar));
+ 	failure("bsdtar does not pad archives written directly to regular files");
+ 	assertFileSize("archive1.tar", 2048);
+ 	assertEmptyFile("test1.out");
+@@ -46,24 +52,24 @@ DEFINE_TEST(test_option_b)
+ 	 * Bsdtar does pad to the block size if the output is going to a socket.
+ 	 */
+ 	/* Default is -b 20 */
+-	assertEqualInt(0, systemf("%s -cf - file1 2>test2.err | cat >archive2.tar ", testprog));
++	assertEqualInt(0, systemf("%s -cf - file1 2>test2.err | cat >archive2.tar ", testprog_ustar));
+ 	failure("bsdtar does pad archives written to pipes");
+ 	assertFileSize("archive2.tar", 10240);
+ 	assertEmptyFile("test2.err");
+ 
+-	assertEqualInt(0, systemf("%s -cf - -b 20 file1 2>test3.err | cat >archive3.tar ", testprog));
++	assertEqualInt(0, systemf("%s -cf - -b 20 file1 2>test3.err | cat >archive3.tar ", testprog_ustar));
+ 	assertFileSize("archive3.tar", 10240);
+ 	assertEmptyFile("test3.err");
+ 
+-	assertEqualInt(0, systemf("%s -cf - -b 10 file1 2>test4.err | cat >archive4.tar ", testprog));
++	assertEqualInt(0, systemf("%s -cf - -b 10 file1 2>test4.err | cat >archive4.tar ", testprog_ustar));
+ 	assertFileSize("archive4.tar", 5120);
+ 	assertEmptyFile("test4.err");
+ 
+-	assertEqualInt(0, systemf("%s -cf - -b 1 file1 2>test5.err | cat >archive5.tar ", testprog));
++	assertEqualInt(0, systemf("%s -cf - -b 1 file1 2>test5.err | cat >archive5.tar ", testprog_ustar));
+ 	assertFileSize("archive5.tar", 2048);
+ 	assertEmptyFile("test5.err");
+ 
+-	assertEqualInt(0, systemf("%s -cf - -b 8192 file1 2>test6.err | cat >archive6.tar ", testprog));
++	assertEqualInt(0, systemf("%s -cf - -b 8192 file1 2>test6.err | cat >archive6.tar ", testprog_ustar));
+ 	assertFileSize("archive6.tar", 4194304);
+ 	assertEmptyFile("test6.err");
+ 
diff --git a/SOURCES/libarchive-3.1.3-CVE-2013-0211_read_buffer_overflow.patch b/SOURCES/libarchive-3.1.3-CVE-2013-0211_read_buffer_overflow.patch
new file mode 100644
index 0000000..78427ce
--- /dev/null
+++ b/SOURCES/libarchive-3.1.3-CVE-2013-0211_read_buffer_overflow.patch
@@ -0,0 +1,32 @@
+From 22531545514043e04633e1c015c7540b9de9dbe4 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Fri, 22 Mar 2013 23:48:41 -0700
+Subject: [PATCH] Limit write requests to at most INT_MAX. This prevents a
+ certain common programming error (passing -1 to write) from leading to other
+ problems deeper in the library.
+
+---
+ libarchive/archive_write.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
+index eede5e0..be85621 100644
+--- a/libarchive/archive_write.c
++++ b/libarchive/archive_write.c
+@@ -673,8 +673,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));
+ }
+-- 
+1.8.1
+
diff --git a/SOURCES/libarchive-3.3.2-CVE-2018-1000877.patch b/SOURCES/libarchive-3.3.2-CVE-2018-1000877.patch
new file mode 100644
index 0000000..e980aa6
--- /dev/null
+++ b/SOURCES/libarchive-3.3.2-CVE-2018-1000877.patch
@@ -0,0 +1,34 @@
+From 88311f46cdfc719d26bb99d3b47944eb92ceae02 Mon Sep 17 00:00:00 2001
+From: Ondrej Dubaj <odubaj@redhat.com>
+Date: Tue, 30 Apr 2019 11:50:33 +0200
+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(+)
+
+diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
+index c4a8278..3f88eef 100644
+--- a/libarchive/archive_read_support_format_rar.c
++++ b/libarchive/archive_read_support_format_rar.c
+@@ -2317,6 +2317,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,
+-- 
+2.17.1
+
diff --git a/SOURCES/libarchive-3.3.2-CVE-2018-1000878.patch b/SOURCES/libarchive-3.3.2-CVE-2018-1000878.patch
new file mode 100644
index 0000000..2736827
--- /dev/null
+++ b/SOURCES/libarchive-3.3.2-CVE-2018-1000878.patch
@@ -0,0 +1,75 @@
+From d00ccaf8c20efbd009964e3e2697d26907d14163 Mon Sep 17 00:00:00 2001
+From: Ondrej Dubaj <odubaj@redhat.com>
+Date: Tue, 30 Apr 2019 11:36:08 +0200
+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(+)
+
+diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
+index cbb14c3..c4a8278 100644
+--- a/libarchive/archive_read_support_format_rar.c
++++ b/libarchive/archive_read_support_format_rar.c
+@@ -258,6 +258,7 @@ struct rar
+   struct data_block_offsets *dbo;
+   unsigned int cursor;
+   unsigned int nodes;
++  char filename_must_match;
+ 
+   /* LZSS members */
+   struct huffman_code maincode;
+@@ -1570,6 +1571,12 @@ read_header(struct archive_read *a, struct archive_entry *entry,
+     }
+     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);
+@@ -2938,12 +2945,14 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
+     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);
+-- 
+2.17.1
+
diff --git a/SPECS/libarchive.spec b/SPECS/libarchive.spec
new file mode 100644
index 0000000..608e3c3
--- /dev/null
+++ b/SPECS/libarchive.spec
@@ -0,0 +1,375 @@
+Name:           libarchive
+Version:        3.1.2
+Release:        12%{?dist}
+Summary:        A library for handling streaming archive formats
+
+Group:          System Environment/Libraries
+License:        BSD
+URL:            http://www.libarchive.org/
+Source0:        http://www.libarchive.org/downloads/%{name}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+
+BuildRequires: bison
+BuildRequires: sharutils
+BuildRequires: zlib-devel
+BuildRequires: bzip2-devel
+BuildRequires: xz-devel
+BuildRequires: lzo-devel
+BuildRequires: e2fsprogs-devel
+BuildRequires: libacl-devel
+BuildRequires: libattr-devel
+BuildRequires: openssl-devel
+BuildRequires: libxml2-devel
+BuildRequires: automake autoconf libtool
+
+
+# CVE-2013-0211 libarchive: read buffer overflow on 64-bit systems
+# https://bugzilla.redhat.com/show_bug.cgi?id=927105
+Patch0: libarchive-3.1.3-CVE-2013-0211_read_buffer_overflow.patch
+
+Patch1: libarchive-3.1.2-testsuite.patch
+
+# A bunch of security patches from 2016 summer
+Patch2: libarchive-3.1.2-rhbz-1347085.patch
+Patch3: libarchive-3.1.2-rhbz-1347086.patch
+Patch4: libarchive-3.1.2-CVE-2015-8916-CVE-2015-8917.patch
+Patch5: libarchive-3.1.2-CVE-2015-8919.patch
+Patch6: libarchive-3.1.2-CVE-2015-8920.patch
+Patch7: libarchive-3.1.2-CVE-2015-8921.patch
+Patch8: libarchive-3.1.2-CVE-2015-8922.patch
+Patch9: libarchive-3.1.2-CVE-2015-8923.patch
+Patch10: libarchive-3.1.2-CVE-2015-8924.patch
+Patch11: libarchive-3.1.2-CVE-2015-8925.patch
+Patch12: libarchive-3.1.2-CVE-2015-8926.patch
+Patch13: libarchive-3.1.2-CVE-2015-8928.patch
+Patch14: libarchive-3.1.2-CVE-2015-8930.patch
+Patch15: libarchive-3.1.2-CVE-2015-8931.patch
+Patch16: libarchive-3.1.2-CVE-2015-8932.patch
+Patch17: libarchive-3.1.2-CVE-2015-8934.patch
+Patch18: libarchive-3.1.2-CVE-2016-4300.patch
+Patch19: libarchive-3.1.2-CVE-2016-4302.patch
+Patch20: libarchive-3.1.2-CVE-2016-4809.patch
+Patch21: libarchive-3.1.2-CVE-2016-5844.patch
+Patch22: libarchive-3.1.2-CVE-2016-1541.patch
+Patch23: libarchive-3.1.2-CVE-2016-5418.patch
+Patch24: libarchive-3.1.2-CVE-2016-5418-variation.patch
+Patch25: libarchive-3.1.2-CVE-2017-14503.patch
+Patch26: libarchive-3.1.2-CVE-2019-1000019.patch
+Patch27: libarchive-3.1.2-CVE-2019-1000020.patch
+Patch28: libarchive-3.3.2-CVE-2018-1000878.patch
+Patch29: libarchive-3.3.2-CVE-2018-1000877.patch
+
+%description
+Libarchive is a programming library that can create and read several different
+streaming archive formats, including most popular tar variants, several cpio
+formats, and both BSD and GNU ar variants. It can also write shar archives and
+read ISO9660 CDROM images and ZIP archives.
+
+%package        devel
+Summary:        Development files for %{name}
+Group:          Development/Libraries
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+
+%description    devel
+The %{name}-devel package contains libraries and header files for
+developing applications that use %{name}.
+
+
+%package -n     bsdtar
+Summary:        Manipulate tape archives
+Group:          Applications/File
+Requires:       %{name} = %{version}-%{release}
+
+%description -n bsdtar
+The bsdtar package contains standalone bsdtar utility split off regular
+libarchive packages.
+
+
+%package -n     bsdcpio
+Summary:        Copy files to and from archives
+Group:          Applications/File
+Requires:       %{name} = %{version}-%{release}
+
+%description -n bsdcpio
+The bsdcpio package contains standalone bsdcpio utility split off regular
+libarchive packages.
+
+%global _hardened_build 1
+
+%prep
+%setup -q -n %{name}-%{version}
+%patch0 -p1 -b .CVE-2013-0211
+# fix bugs in testsuite
+# ~> upstream ~> 26629c191a & b539b2e597 & 9caa49246
+%patch1 -p1 -b .fix-testsuite
+
+%patch2 -p1 -b .rhbz-1347085
+%patch3 -p1 -b .rhbz-1347086
+%patch4 -p1 -b .CVE-2015-8916-CVE-2015-8917
+%patch5 -p1 -b .CVE-2015-8919
+%patch6 -p1 -b .CVE-2015-8920
+%patch7 -p1 -b .CVE-2015-8921
+%patch8 -p1 -b .CVE-2015-8922
+%patch9 -p1 -b .CVE-2015-8923
+%patch10 -p1 -b .CVE-2015-8924
+%patch11 -p1 -b .CVE-2015-8925
+%patch12 -p1 -b .CVE-2015-8926
+%patch13 -p1 -b .CVE-2015-8928
+%patch14 -p1 -b .CVE-2015-8930
+%patch15 -p1 -b .CVE-2015-8931
+%patch16 -p1 -b .CVE-2015-8932
+%patch17 -p1 -b .CVE-2015-8934
+%patch18 -p1 -b .CVE-2016-4300
+%patch19 -p1 -b .CVE-2016-4302
+%patch20 -p1 -b .CVE-2016-4809
+%patch21 -p1 -b .CVE-2016-5844
+%patch22 -p1 -b .CVE-2016-1541
+%patch23 -p1 -b .CVE-2016-5418
+%patch24 -p1 -b .CVE-2016-5418-var
+%patch25 -p1 -b .CVE-2017-14503
+%patch26 -p1 -b .CVE-2019-1000019
+%patch27 -p1 -b .CVE-2019-1000020
+%patch28 -p1 -b .CVE-2019-1000878
+%patch29 -p1 -b .CVE-2019-1000877
+
+
+%build
+build/autogen.sh
+%configure --disable-static --disable-rpath
+# remove rpaths
+sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
+sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
+
+test -z "$V" && verbose_make="V=1"
+make %{?_smp_mflags} $verbose_make
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
+
+
+%check
+run_testsuite()
+{
+    LD_LIBRARY_PATH=`pwd`/.libs make check -j1
+    res=$?
+    echo $res
+    if [ $res -ne 0 ]; then
+        # error happened - try to extract in koji as much info as possible
+        cat test-suite.log
+        echo "========================="
+        err=`cat test-suite.log | grep "Details for failing tests" | cut -d: -f2`
+        for i in $err; do
+            find $i -printf "%p\n    ~> a: %a\n    ~> c: %c\n    ~> t: %t\n    ~> %s B\n"
+            echo "-------------------------"
+            cat $i/*.log
+        done
+        return 1
+    else
+        find -name '*_test.log' -exec cat {} +
+        return 0
+    fi
+}
+
+# On a ppc/ppc64 is some race condition causing 'make check' fail on ppc
+# when both 32 and 64 builds are done in parallel on the same machine in
+# koji.  Try to run once again if failed.
+%ifarch ppc
+run_testsuite || run_testsuite
+%else
+run_testsuite
+%endif
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%post -p /sbin/ldconfig
+
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%defattr(-,root,root,-)
+%doc COPYING README NEWS
+%{_libdir}/libarchive.so.13*
+%{_mandir}/*/cpio.*
+%{_mandir}/*/mtree.*
+%{_mandir}/*/tar.*
+
+%files devel
+%defattr(-,root,root,-)
+%doc
+%{_includedir}/*.h
+%{_mandir}/*/archive*
+%{_mandir}/*/libarchive*
+%{_libdir}/libarchive.so
+%{_libdir}/pkgconfig/libarchive.pc
+
+%files -n bsdtar
+%defattr(-,root,root,-)
+%doc COPYING README NEWS
+%{_bindir}/bsdtar
+%{_mandir}/*/bsdtar*
+
+%files -n bsdcpio
+%defattr(-,root,root,-)
+%doc COPYING README NEWS
+%{_bindir}/bsdcpio
+%{_mandir}/*/bsdcpio*
+
+
+%changelog
+* Tue Apr 30 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.1.2-12
+- fixed use after free in RAR decoder (#1700749)
+- fixed double free in RAR decoder (#1700748)
+
+* Fri Feb 22 2019 Pavel Raiskup <praiskup@redhat.com> - 3.1.2-11
+- fix out-of-bounds read within lha_read_data_none() (CVE-2017-14503)
+- fix crash on crafted 7zip archives (CVE-2019-1000019)
+- fix infinite loop in ISO9660 (CVE-2019-1000020)
+
+* Fri Aug 12 2016 Petr Kubat <pkubat@redhat.com> - 3.1.2-10
+- Fixes variation of CVE-2016-5418: Hard links could include ".." in their path.
+
+* Thu Aug 11 2016 Petr Kubat <pkubat@redhat.com> - 3.1.2-9
+- Fixes CVE-2016-5418: Archive Entry with type 1 (hardlink) causes file overwrite (#1365777)
+
+* Fri Jul 08 2016 Pavel Raiskup <praiskup@redhat.com> - 3.1.2-8
+- a bunch of security fixes (rhbz#1353065)
+
+* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 3.1.2-7
+- Mass rebuild 2014-01-24
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 3.1.2-6
+- Mass rebuild 2013-12-27
+
+* Mon Jul 22 2013 Pavel Raiskup <praiskup@redhat.com> - 3.1.2-5
+- try to workaround racy testsuite fail
+
+* Sun Jun 30 2013 Pavel Raiskup <praiskup@redhat.com> - 3.1.2-4
+- enable testsuite in the %%check phase
+
+* Mon Jun 24 2013 Pavel Raiskup <praiskup@redhat.com> - 3.1.2-3
+- bsdtar/bsdcpio should require versioned libarchive
+
+* Wed Apr  3 2013 Tomas Bzatek <tbzatek@redhat.com> - 3.1.2-2
+- Remove libunistring-devel build require
+
+* Thu Mar 28 2013 Tomas Bzatek <tbzatek@redhat.com> - 3.1.2-1
+- Update to 3.1.2
+- Fix CVE-2013-0211: read buffer overflow on 64-bit systems (#927105)
+
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.1.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Mon Jan 14 2013 Tomas Bzatek <tbzatek@redhat.com> - 3.1.1-1
+- Update to 3.1.1
+- NEWS seems to be valid UTF-8 nowadays
+
+* Wed Oct 03 2012 Pavel Raiskup <praiskup@redhat.com> - 3.0.4-3
+- better install manual pages for libarchive/bsdtar/bsdcpio (# ... )
+- several fedora-review fixes ...:
+- Source0 has moved to github.com
+- remove trailing white spaces
+- repair summary to better describe bsdtar/cpiotar utilities
+
+* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.0.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Mon May  7 2012 Tomas Bzatek <tbzatek@redhat.com> - 3.0.4-1
+- Update to 3.0.4
+
+* Wed Feb  1 2012 Tomas Bzatek <tbzatek@redhat.com> - 3.0.3-2
+- Enable bsdtar and bsdcpio in separate subpackages (#786400)
+
+* Fri Jan 13 2012 Tomas Bzatek <tbzatek@redhat.com> - 3.0.3-1
+- Update to 3.0.3
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.0.0-0.3.a
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Tue Nov 15 2011 Rex Dieter <rdieter@fedoraproject.org> 3.0.0-0.2.a
+- track files/sonames closer, so abi bumps aren't a surprise
+- tighten subpkg deps via %%_isa
+
+* Mon Nov 14 2011 Tomas Bzatek <tbzatek@redhat.com> - 3.0.0-0.1.a
+- Update to 3.0.0a (alpha release)
+
+* Mon Sep  5 2011 Tomas Bzatek <tbzatek@redhat.com> - 2.8.5-1
+- Update to 2.8.5
+
+* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.8.4-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Thu Jan 13 2011 Tomas Bzatek <tbzatek@redhat.com> - 2.8.4-2
+- Rebuild for new xz-libs
+
+* Wed Jun 30 2010 Tomas Bzatek <tbzatek@redhat.com> - 2.8.4-1
+- Update to 2.8.4
+
+* Fri Jun 25 2010 Tomas Bzatek <tbzatek@redhat.com> - 2.8.3-2
+- Fix ISO9660 reader data type mismatches (#597243)
+
+* Tue Mar 16 2010 Tomas Bzatek <tbzatek@redhat.com> - 2.8.3-1
+- Update to 2.8.3
+
+* Mon Mar  8 2010 Tomas Bzatek <tbzatek@redhat.com> - 2.8.1-1
+- Update to 2.8.1
+
+* Fri Feb  5 2010 Tomas Bzatek <tbzatek@redhat.com> - 2.8.0-1
+- Update to 2.8.0
+
+* Wed Jan  6 2010 Tomas Bzatek <tbzatek@redhat.com> - 2.7.902a-1
+- Update to 2.7.902a
+
+* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 2.7.1-2
+- rebuilt with new openssl
+
+* Fri Aug  7 2009 Tomas Bzatek <tbzatek@redhat.com> 2.7.1-1
+- Update to 2.7.1
+- Drop deprecated lzma dependency, libxz handles both formats
+
+* Mon Jul 27 2009 Tomas Bzatek <tbzatek@redhat.com> 2.7.0-3
+- Enable XZ compression format
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.7.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Tue May 12 2009 Tomas Bzatek <tbzatek@redhat.com> 2.7.0-1
+- Update to 2.7.0
+
+* Fri Mar  6 2009 Tomas Bzatek <tbzatek@redhat.com> 2.6.2-1
+- Update to 2.6.2
+
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.6.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Mon Feb 16 2009 Tomas Bzatek <tbzatek@redhat.com> 2.6.1-1
+- Update to 2.6.1
+
+* Thu Jan  8 2009 Tomas Bzatek <tbzatek@redhat.com> 2.6.0-1
+- Update to 2.6.0
+
+* Mon Dec 15 2008 Tomas Bzatek <tbzatek@redhat.com> 2.5.904a-1
+- Update to 2.5.904a
+
+* Tue Dec  9 2008 Tomas Bzatek <tbzatek@redhat.com> 2.5.903a-2
+- Add LZMA support
+
+* Mon Dec  8 2008 Tomas Bzatek <tbzatek@redhat.com> 2.5.903a-1
+- Update to 2.5.903a
+
+* Tue Jul 22 2008 Tomas Bzatek <tbzatek@redhat.com> 2.5.5-1
+- Update to 2.5.5
+
+* Wed Apr  2 2008 Tomas Bzatek <tbzatek@redhat.com> 2.4.17-1
+- Update to 2.4.17
+
+* Wed Mar 19 2008 Tomas Bzatek <tbzatek@redhat.com> 2.4.14-1
+- Initial packaging