Blame SOURCES/libarchive-3.1.2-CVE-2016-1541.patch

58251f
From 1966a9c18521a15d79f64fe893040e3fdb5a3790 Mon Sep 17 00:00:00 2001
58251f
From: Tim Kientzle <kientzle@acm.org>
58251f
Date: Sun, 24 Apr 2016 17:13:45 -0700
58251f
Subject: [PATCH] Issue #656: Fix CVE-2016-1541, VU#862384
58251f
58251f
When reading OS X metadata entries in Zip archives that were stored
58251f
without compression, libarchive would use the uncompressed entry size
58251f
to allocate a buffer but would use the compressed entry size to limit
58251f
the amount of data copied into that buffer.  Since the compressed
58251f
and uncompressed sizes are provided by data in the archive itself,
58251f
an attacker could manipulate these values to write data beyond
58251f
the end of the allocated buffer.
58251f
58251f
This fix provides three new checks to guard against such
58251f
manipulation and to make libarchive generally more robust when
58251f
handling this type of entry:
58251f
 1. If an OS X metadata entry is stored without compression,
58251f
    abort the entire archive if the compressed and uncompressed
58251f
    data sizes do not match.
58251f
 2. When sanity-checking the size of an OS X metadata entry,
58251f
    abort this entry if either the compressed or uncompressed
58251f
    size is larger than 4MB.
58251f
 3. When copying data into the allocated buffer, check the copy
58251f
    size against both the compressed entry size and uncompressed
58251f
    entry size.
58251f
---
58251f
 libarchive/archive_read_support_format_zip.c | 13 +++++++++++++
58251f
 1 file changed, 13 insertions(+)
58251f
58251f
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
58251f
index 1aed84a..fa3db11 100644
58251f
--- a/libarchive/archive_read_support_format_zip.c
58251f
+++ b/libarchive/archive_read_support_format_zip.c
58251f
@@ -560,6 +560,11 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
58251f
 
58251f
 	switch(rsrc->compression) {
58251f
 	case 0:  /* No compression. */
58251f
+		if (rsrc->uncompressed_size != rsrc->compressed_size) {
58251f
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
58251f
+			    "Malformed OS X metadata entry: inconsistent size");
58251f
+			return (ARCHIVE_FATAL);
58251f
+		}
58251f
 #ifdef HAVE_ZLIB_H
58251f
 	case 8: /* Deflate compression. */
58251f
 #endif
58251f
@@ -580,6 +585,12 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
58251f
 		    (intmax_t)rsrc->uncompressed_size);
58251f
 		return (ARCHIVE_WARN);
58251f
 	}
58251f
+	if (rsrc->compressed_size > (4 * 1024 * 1024)) {
58251f
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
58251f
+		    "Mac metadata is too large: %jd > 4M bytes",
58251f
+		    (intmax_t)rsrc->compressed_size);
58251f
+		return (ARCHIVE_WARN);
58251f
+	}
58251f
 
58251f
 	metadata = malloc((size_t)rsrc->uncompressed_size);
58251f
 	if (metadata == NULL) {
58251f
@@ -619,6 +630,8 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
58251f
 			bytes_avail = remaining_bytes;
58251f
 		switch(rsrc->compression) {
58251f
 		case 0:  /* No compression. */
58251f
+			if ((size_t)bytes_avail > metadata_bytes)
58251f
+				bytes_avail = metadata_bytes;
58251f
 			memcpy(mp, p, bytes_avail);
58251f
 			bytes_used = (size_t)bytes_avail;
58251f
 			metadata_bytes -= bytes_used;
58251f
-- 
58251f
2.7.4
58251f