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-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/SPECS/libarchive.spec b/SPECS/libarchive.spec
index 92ea6d0..347c162 100644
--- a/SPECS/libarchive.spec
+++ b/SPECS/libarchive.spec
@@ -1,6 +1,6 @@
 Name:           libarchive
 Version:        3.1.2
-Release:        7%{?dist}
+Release:        10%{?dist}
 Summary:        A library for handling streaming archive formats
 
 Group:          System Environment/Libraries
@@ -30,6 +30,31 @@ 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
+
 %description
 Libarchive is a programming library that can create and read several different
 streaming archive formats, including most popular tar variants, several cpio
@@ -65,6 +90,7 @@ Requires:       %{name} = %{version}-%{release}
 The bsdcpio package contains standalone bsdcpio utility split off regular
 libarchive packages.
 
+%global _hardened_build 1
 
 %prep
 %setup -q -n %{name}-%{version}
@@ -73,6 +99,30 @@ libarchive packages.
 # ~> 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
+
 
 %build
 build/autogen.sh
@@ -109,6 +159,7 @@ run_testsuite()
         done
         return 1
     else
+        find -name '*_test.log' -exec cat {} +
         return 0
     fi
 }
@@ -164,6 +215,15 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* 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