Blame SOURCES/libarchive-3.1.2-CVE-2015-8923.patch

58251f
From 9e0689cff30f64defb2691003143a7ad3126c74a Mon Sep 17 00:00:00 2001
58251f
From: Tim Kientzle <kientzle@acm.org>
58251f
Date: Sat, 7 Feb 2015 19:03:43 -0800
58251f
Subject: [PATCH] Issue 406: Segfault on malformed Zip archive
58251f
58251f
Issue here was reading a size field as a signed number
58251f
and then using that as an offset.  Fixed by correctly
58251f
masking the size value to an unsigned result.
58251f
58251f
Includes test based on the archive provided in the issue report.
58251f
58251f
---
58251f
diff --git a/Makefile.am b/Makefile.am
58251f
index f6e1e20..fb90b9c 100644
58251f
--- a/Makefile.am
58251f
+++ b/Makefile.am
58251f
@@ -428,6 +428,7 @@ libarchive_test_SOURCES=					\
58251f
 	libarchive/test/test_read_format_zip_comment_stored.c	\
58251f
 	libarchive/test/test_read_format_zip_filename.c		\
58251f
 	libarchive/test/test_read_format_zip_mac_metadata.c	\
58251f
+	libarchive/test/test_read_format_zip_malformed.c	\
58251f
 	libarchive/test/test_read_format_zip_sfx.c		\
58251f
 	libarchive/test/test_read_large.c			\
58251f
 	libarchive/test/test_read_pax_truncated.c		\
58251f
@@ -685,6 +686,7 @@ libarchive_test_EXTRA_DIST=\
58251f
 	libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu	\
58251f
 	libarchive/test/test_read_format_zip_length_at_end.zip.uu	\
58251f
 	libarchive/test/test_read_format_zip_mac_metadata.zip.uu	\
58251f
+	libarchive/test/test_read_format_zip_malformed1.zip.uu		\
58251f
 	libarchive/test/test_read_format_zip_sfx.uu			\
58251f
 	libarchive/test/test_read_format_zip_symlink.zip.uu		\
58251f
 	libarchive/test/test_read_format_zip_ux.zip.uu			\
58251f
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
58251f
index 450a6f7..1aed84a 100644
58251f
--- a/libarchive/archive_read_support_format_zip.c
58251f
+++ b/libarchive/archive_read_support_format_zip.c
58251f
@@ -1701,7 +1701,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
58251f
 			if (datasize >= 1 && p[offset] == 1) {/* version=1 */
58251f
 				if (datasize >= 4) {
58251f
 					/* get a uid size. */
58251f
-					uidsize = p[offset+1];
58251f
+					uidsize = 0xff & (int)p[offset+1];
58251f
 					if (uidsize == 2)
58251f
 						zip_entry->uid =
58251f
 						    archive_le16dec(
58251f
@@ -1713,7 +1713,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
58251f
 				}
58251f
 				if (datasize >= (2 + uidsize + 3)) {
58251f
 					/* get a gid size. */
58251f
-					gidsize = p[offset+2+uidsize];
58251f
+					gidsize = 0xff & (int)p[offset+2+uidsize];
58251f
 					if (gidsize == 2)
58251f
 						zip_entry->gid =
58251f
 						    archive_le16dec(
58251f
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
58251f
index 08770d9..2dc1740 100644
58251f
--- a/libarchive/test/CMakeLists.txt
58251f
+++ b/libarchive/test/CMakeLists.txt
58251f
@@ -143,6 +143,7 @@ IF(ENABLE_TEST)
58251f
     test_read_format_zip_comment_stored.c
58251f
     test_read_format_zip_filename.c
58251f
     test_read_format_zip_mac_metadata.c
58251f
+    test_read_format_zip_malformed.c
58251f
     test_read_format_zip_sfx.c
58251f
     test_read_large.c
58251f
     test_read_pax_truncated.c
58251f
diff --git a/libarchive/test/test_read_format_zip_malformed.c b/libarchive/test/test_read_format_zip_malformed.c
58251f
new file mode 100644
58251f
index 0000000..2327d91
58251f
--- /dev/null
58251f
+++ b/libarchive/test/test_read_format_zip_malformed.c
58251f
@@ -0,0 +1,61 @@
58251f
+/*-
58251f
+ * Copyright (c) 2003-2007 Tim Kientzle
58251f
+ * Copyright (c) 2011 Michihiro NAKAJIMA
58251f
+ * All rights reserved.
58251f
+ *
58251f
+ * Redistribution and use in source and binary forms, with or without
58251f
+ * modification, are permitted provided that the following conditions
58251f
+ * are met:
58251f
+ * 1. Redistributions of source code must retain the above copyright
58251f
+ *    notice, this list of conditions and the following disclaimer.
58251f
+ * 2. Redistributions in binary form must reproduce the above copyright
58251f
+ *    notice, this list of conditions and the following disclaimer in the
58251f
+ *    documentation and/or other materials provided with the distribution.
58251f
+ *
58251f
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
58251f
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
58251f
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
58251f
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
58251f
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
58251f
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58251f
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58251f
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58251f
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58251f
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58251f
+ */
58251f
+#include "test.h"
58251f
+__FBSDID("$FreeBSD$");
58251f
+
58251f
+static void
58251f
+test_malformed1(void)
58251f
+{
58251f
+	const char *refname = "test_read_format_zip_malformed1.zip";
58251f
+	struct archive *a;
58251f
+	struct archive_entry *ae;
58251f
+	char *p;
58251f
+	size_t s;
58251f
+
58251f
+	extract_reference_file(refname);
58251f
+
58251f
+	/* Verify with seeking reader. */
58251f
+	assert((a = archive_read_new()) != NULL);
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
58251f
+
58251f
+	/* Verify with streaming reader. */
58251f
+	p = slurpfile(&s, refname);
58251f
+	assert((a = archive_read_new()) != NULL);
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
58251f
+	assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
58251f
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
58251f
+}
58251f
+
58251f
+DEFINE_TEST(test_read_format_zip_malformed)
58251f
+{
58251f
+	test_malformed1();
58251f
+}
58251f
diff --git a/libarchive/test/test_read_format_zip_malformed1.zip.uu b/libarchive/test/test_read_format_zip_malformed1.zip.uu
58251f
new file mode 100644
58251f
index 0000000..cbd21a8
58251f
--- /dev/null
58251f
+++ b/libarchive/test/test_read_format_zip_malformed1.zip.uu
58251f
@@ -0,0 +1,5 @@
58251f
+begin 644 test_read_format_zip_malformed1.zip
58251f
+M4$L#!#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`$`!P`,#`P,#`P"0`P,#`P,#`P
58251f
+1,#!U>`L``80P,#`P,#`P,#``
58251f
+`
58251f
+end
58251f
-- 
58251f
2.7.4
58251f