File CVE-2016-1541.patch of Package libarchive.2786

commit d0331e8e5b05b475f20b1f3101fe1ad772d7e7e7
Author: Tim Kientzle <kientzle@acm.org>
Date:   Sun Apr 24 17:13:45 2016 -0700

    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.

Index: libarchive-3.1.2/libarchive/archive_read_support_format_zip.c
===================================================================
--- libarchive-3.1.2.orig/libarchive/archive_read_support_format_zip.c
+++ libarchive-3.1.2/libarchive/archive_read_support_format_zip.c
@@ -560,6 +560,11 @@ zip_read_mac_metadata(struct archive_rea
 
 	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_rea
 		    (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_rea
 			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;
openSUSE Build Service is sponsored by