Parcourir la source

security fix: fix infinite loop in corrupt archives handling (FreeBSD-SA-06:24.libarchive)

Ralf S. Engelschall il y a 19 ans
Parent
commit
03f7a5d291
2 fichiers modifiés avec 54 ajouts et 1 suppressions
  1. 51 0
      libarchive/libarchive.patch
  2. 3 1
      libarchive/libarchive.spec

+ 51 - 0
libarchive/libarchive.patch

@@ -0,0 +1,51 @@
+Index: libarchive/archive_read_support_compression_none.c
+--- libarchive/archive_read_support_compression_none.c.orig	2006-09-05 08:00:47 +0200
++++ libarchive/archive_read_support_compression_none.c	2006-11-08 17:06:23 +0100
+@@ -257,7 +257,9 @@
+ }
+ 
+ /*
+- * Skip at most request bytes. Skipped data is marked as consumed.
++ * Skip forward by exactly the requested bytes or else return
++ * ARCHIVE_FATAL.  Note that this differs from the contract for
++ * read_ahead, which does not gaurantee a minimum count.
+  */
+ static ssize_t
+ archive_decompressor_none_skip(struct archive *a, size_t request)
+@@ -287,9 +289,7 @@
+ 	if (request == 0)
+ 		return (total_bytes_skipped);
+ 	/*
+-	 * If no client_skipper is provided, just read the old way. It is very
+-	 * likely that after skipping, the request has not yet been fully
+-	 * satisfied (and is still > 0). In that case, read as well.
++	 * If a client_skipper was provided, try that first.
+ 	 */
+ 	if (a->client_skipper != NULL) {
+ 		bytes_skipped = (a->client_skipper)(a, a->client_data,
+@@ -307,6 +307,12 @@
+ 		a->raw_position += bytes_skipped;
+ 		state->client_avail = state->client_total = 0;
+ 	}
++	/*
++	 * Note that client_skipper will usually not satisfy the
++	 * full request (due to low-level blocking concerns),
++	 * so even if client_skipper is provided, we may still
++	 * have to use ordinary reads to finish out the request.
++	 */
+ 	while (request > 0) {
+ 		const void* dummy_buffer;
+ 		ssize_t bytes_read;
+@@ -314,6 +320,12 @@
+ 		    &dummy_buffer, request);
+ 		if (bytes_read < 0)
+ 			return (bytes_read);
++		if (bytes_read == 0) {
++			/* We hit EOF before we satisfied the skip request. */
++			archive_set_error(a, ARCHIVE_ERRNO_MISC,
++			    "Truncated input file (need to skip %d bytes)", (int)request);
++			return (ARCHIVE_FATAL);
++		}
+ 		assert(bytes_read >= 0); /* precondition for cast below */
+ 		min = minimum((size_t)bytes_read, request);
+ 		bytes_read = archive_decompressor_none_read_consume(a, min);

+ 3 - 1
libarchive/libarchive.spec

@@ -33,10 +33,11 @@ Class:        EVAL
 Group:        Archiver
 License:      MIT-style
 Version:      2.0a1
-Release:      20061101
+Release:      20061108
 
 #   list of sources
 Source0:      http://people.freebsd.org/~kientzle/libarchive/src/libarchive-%{version}.tar.gz
+Patch0:       libarchive.patch
 
 #   build information
 Prefix:       %{l_prefix}
@@ -63,6 +64,7 @@ AutoReqProv:  no
 
 %prep
     %setup -q
+    %patch -p0
 
 %build
     CC="%{l_cc}" \