[libarchive/el5] Security fixes (CVE-2011-1777, CVE-2011-1778) (#773505)

Niels de Vos devos at fedoraproject.org
Sat Jan 14 10:39:29 UTC 2012


commit 133909d4a76fef9379c4683332bfeab5b84b024d
Author: Niels de Vos <devos at fedoraproject.org>
Date:   Sat Jan 14 10:39:04 2012 +0000

    Security fixes (CVE-2011-1777, CVE-2011-1778) (#773505)

 libarchive-2.8.4-CVE-2011-1777.patch   |  157 +++++++++++++++++++++++
 libarchive-2.8.4-CVE-2011-1778-2.patch |  213 ++++++++++++++++++++++++++++++++
 libarchive.spec                        |   11 ++-
 3 files changed, 380 insertions(+), 1 deletions(-)
---
diff --git a/libarchive-2.8.4-CVE-2011-1777.patch b/libarchive-2.8.4-CVE-2011-1777.patch
new file mode 100644
index 0000000..6f77337
--- /dev/null
+++ b/libarchive-2.8.4-CVE-2011-1777.patch
@@ -0,0 +1,157 @@
+diff -urN a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
+--- a/libarchive/archive_read_support_format_iso9660.c	2011-09-16 14:21:15.996720821 -0300
++++ b/libarchive/archive_read_support_format_iso9660.c	2011-09-16 14:47:16.159293897 -0300
+@@ -405,12 +405,12 @@
+ static inline void cache_add_to_next_of_parent(struct iso9660 *iso9660,
+ 		    struct file_info *file);
+ static inline struct file_info *cache_get_entry(struct iso9660 *iso9660);
+-static void	heap_add_entry(struct heap_queue *heap,
++static int	heap_add_entry(struct archive_read *a, struct heap_queue *heap,
+ 		    struct file_info *file, uint64_t key);
+ static struct file_info *heap_get_entry(struct heap_queue *heap);
+ 
+-#define add_entry(iso9660, file)	\
+-	heap_add_entry(&((iso9660)->pending_files), file, file->offset)
++#define add_entry(arch, iso9660, file)	\
++	heap_add_entry(arch, &((iso9660)->pending_files), file, file->offset)
+ #define next_entry(iso9660)		\
+ 	heap_get_entry(&((iso9660)->pending_files))
+ 
+@@ -968,8 +968,9 @@
+ 			if (child == NULL)
+ 				return (ARCHIVE_FATAL);
+ 			if (child->cl_offset)
+-				heap_add_entry(&(iso9660->cl_files),
+-				    child, child->cl_offset);
++				if (heap_add_entry(a, &(iso9660->cl_files),
++				    child, child->cl_offset) != ARCHIVE_OK)
++					return (ARCHIVE_FATAL);
+ 			else {
+ 				if (child->multi_extent || multi != NULL) {
+ 					struct content *con;
+@@ -993,15 +994,19 @@
+ 					con->next = NULL;
+ 					*multi->contents.last = con;
+ 					multi->contents.last = &(con->next);
+-					if (multi == child)
+-						add_entry(iso9660, child);
+-					else {
++					if (multi == child) {
++						if (add_entry(a, iso9660, child)
++						    != ARCHIVE_OK)
++							return (ARCHIVE_FATAL);
++					} else {
+ 						multi->size += child->size;
+ 						if (!child->multi_extent)
+ 							multi = NULL;
+ 					}
+ 				} else
+-					add_entry(iso9660, child);
++					if (add_entry(a, iso9660, child)
++					    != ARCHIVE_OK)
++						return (ARCHIVE_FATAL);
+ 			}
+ 		}
+ 	}
+@@ -1014,7 +1019,8 @@
+ }
+ 
+ static int
+-relocate_dir(struct iso9660 *iso9660, struct file_info *file)
++relocate_dir(struct archive_read *a, struct iso9660 *iso9660,
++	struct file_info *file)
+ {
+ 	struct file_info *re;
+ 
+@@ -1036,7 +1042,9 @@
+ 		return (1);
+ 	} else
+ 		/* This case is wrong pattern. */
+-		heap_add_entry(&(iso9660->re_dirs), re, re->offset);
++		if (heap_add_entry(a, &(iso9660->re_dirs), re, re->offset)
++		    != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 	return (0);
+ }
+ 
+@@ -1063,20 +1071,23 @@
+ 		     strcmp(file->name.s, ".rr_moved") == 0)) {
+ 			iso9660->rr_moved = file;
+ 		} else if (file->re)
+-			heap_add_entry(&(iso9660->re_dirs), file,
+-			    file->offset);
++			if (heap_add_entry(a, &(iso9660->re_dirs), file,
++			    file->offset) != ARCHIVE_OK)
++				return (ARCHIVE_FATAL);
+ 		else
+ 			cache_add_entry(iso9660, file);
+ 	}
+ 	if (file != NULL)
+-		add_entry(iso9660, file);
++		if (add_entry(a, iso9660, file) != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 
+ 	if (iso9660->rr_moved != NULL) {
+ 		/*
+ 		 * Relocate directory which rr_moved has.
+ 		 */
+ 		while ((file = heap_get_entry(&(iso9660->cl_files))) != NULL)
+-			relocate_dir(iso9660, file);
++			if (relocate_dir(a, iso9660, file) != ARCHIVE_OK)
++				return ARCHIVE_FATAL;
+ 
+ 		/* If rr_moved directory still has children,
+ 		 * Add rr_moved into pending_files to show
+@@ -1192,7 +1203,8 @@
+ 			iso9660->seenJoliet = seenJoliet;
+ 		}
+ 		/* Store the root directory in the pending list. */
+-		add_entry(iso9660, file);
++		if (add_entry(a, iso9660, file) != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 		if (iso9660->seenRockridge) {
+ 			a->archive.archive_format =
+ 			    ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
+@@ -2619,8 +2631,8 @@
+ 	return (file);
+ }
+ 
+-static void
+-heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
++static int
++heap_add_entry(struct archive_read *a, struct heap_queue *heap, struct file_info *file, uint64_t key)
+ {
+ 	uint64_t file_key, parent_key;
+ 	int hole, parent;
+@@ -2633,12 +2645,18 @@
+ 		if (heap->allocated < 1024)
+ 			new_size = 1024;
+ 		/* Overflow might keep us from growing the list. */
+-		if (new_size <= heap->allocated)
+-			__archive_errx(1, "Out of memory");
++		if (new_size <= heap->allocated) {
++			archive_set_error(&a->archive,
++			    ENOMEM, "Out of memory");
++			return (ARCHIVE_FATAL);
++		}
+ 		new_pending_files = (struct file_info **)
+ 		    malloc(new_size * sizeof(new_pending_files[0]));
+-		if (new_pending_files == NULL)
+-			__archive_errx(1, "Out of memory");
++		if (new_pending_files == NULL) {
++			archive_set_error(&a->archive,
++			    ENOMEM, "Out of memory");
++			return (ARCHIVE_FATAL);
++		}
+ 		memcpy(new_pending_files, heap->files,
+ 		    heap->allocated * sizeof(new_pending_files[0]));
+ 		if (heap->files != NULL)
+@@ -2665,6 +2683,8 @@
+ 		hole = parent;
+ 	}
+ 	heap->files[0] = file;
++
++	return (ARCHIVE_OK);
+ }
+ 
+ static struct file_info *
diff --git a/libarchive-2.8.4-CVE-2011-1778-2.patch b/libarchive-2.8.4-CVE-2011-1778-2.patch
new file mode 100644
index 0000000..41829fc
--- /dev/null
+++ b/libarchive-2.8.4-CVE-2011-1778-2.patch
@@ -0,0 +1,213 @@
+diff -up libarchive-2.8.3/libarchive/archive_read_support_format_tar.c.CVE-2011-1778 libarchive-2.8.3/libarchive/archive_read_support_format_tar.c
+--- libarchive-2.8.3/libarchive/archive_read_support_format_tar.c.CVE-2011-1778	2010-01-17 01:21:10.000000000 +0100
++++ libarchive-2.8.3/libarchive/archive_read_support_format_tar.c	2011-10-03 13:07:42.000000000 +0200
+@@ -175,14 +175,15 @@ struct tar {
+ static ssize_t	UTF8_mbrtowc(wchar_t *pwc, const char *s, size_t n);
+ static int	archive_block_is_null(const unsigned char *p);
+ static char	*base64_decode(const char *, size_t, size_t *);
+-static void	 gnu_add_sparse_entry(struct tar *,
++static int	gnu_add_sparse_entry(struct archive_read *, struct tar *,
+ 		    off_t offset, off_t remaining);
+ static void	gnu_clear_sparse_list(struct tar *);
+ static int	gnu_sparse_old_read(struct archive_read *, struct tar *,
+ 		    const struct archive_entry_header_gnutar *header);
+-static void	gnu_sparse_old_parse(struct tar *,
++static int	gnu_sparse_old_parse(struct archive_read *a, struct tar *,
+ 		    const struct gnu_sparse *sparse, int length);
+-static int	gnu_sparse_01_parse(struct tar *, const char *);
++static int	gnu_sparse_01_parse(struct archive_read *, struct tar *,
++		    const char *);
+ static ssize_t	gnu_sparse_10_read(struct archive_read *, struct tar *);
+ static int	header_Solaris_ACL(struct archive_read *,  struct tar *,
+ 		    struct archive_entry *, const void *);
+@@ -212,8 +213,8 @@ static int	archive_read_format_tar_skip(
+ static int	archive_read_format_tar_read_header(struct archive_read *,
+ 		    struct archive_entry *);
+ static int	checksum(struct archive_read *, const void *);
+-static int 	pax_attribute(struct tar *, struct archive_entry *,
+-		    char *key, char *value);
++static int 	pax_attribute(struct archive_read *, struct tar *,
++		    struct archive_entry *, char *key, char *value);
+ static int 	pax_header(struct archive_read *, struct tar *,
+ 		    struct archive_entry *, char *attr);
+ static void	pax_time(const char *, int64_t *sec, long *nanos);
+@@ -419,7 +420,9 @@ archive_read_format_tar_read_header(stru
+ 	 * a single block.
+ 	 */
+ 	if (tar->sparse_list == NULL)
+-		gnu_add_sparse_entry(tar, 0, tar->entry_bytes_remaining);
++		if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining)
++		    != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 
+ 	if (r == ARCHIVE_OK) {
+ 		/*
+@@ -1269,7 +1272,7 @@ pax_header(struct archive_read *a, struc
+ 		value = p + 1;
+ 
+ 		/* Identify this attribute and set it in the entry. */
+-		err2 = pax_attribute(tar, entry, key, value);
++		err2 = pax_attribute(a, tar, entry, key, value);
+ 		err = err_combine(err, err2);
+ 
+ 		/* Skip to next line */
+@@ -1395,8 +1398,8 @@ pax_attribute_xattr(struct archive_entry
+  * any of them look useful.
+  */
+ static int
+-pax_attribute(struct tar *tar, struct archive_entry *entry,
+-    char *key, char *value)
++pax_attribute(struct archive_read *a, struct tar *tar,
++	struct archive_entry *entry, char *key, char *value)
+ {
+ 	int64_t s;
+ 	long n;
+@@ -1414,8 +1417,10 @@ pax_attribute(struct tar *tar, struct ar
+ 		if (strcmp(key, "GNU.sparse.offset") == 0) {
+ 			tar->sparse_offset = tar_atol10(value, strlen(value));
+ 			if (tar->sparse_numbytes != -1) {
+-				gnu_add_sparse_entry(tar,
+-				    tar->sparse_offset, tar->sparse_numbytes);
++				if (gnu_add_sparse_entry(a, tar,
++				    tar->sparse_offset, tar->sparse_numbytes)
++				    != ARCHIVE_OK)
++					return(ARCHIVE_FATAL);
+ 				tar->sparse_offset = -1;
+ 				tar->sparse_numbytes = -1;
+ 			}
+@@ -1423,8 +1428,10 @@ pax_attribute(struct tar *tar, struct ar
+ 		if (strcmp(key, "GNU.sparse.numbytes") == 0) {
+ 			tar->sparse_numbytes = tar_atol10(value, strlen(value));
+ 			if (tar->sparse_numbytes != -1) {
+-				gnu_add_sparse_entry(tar,
+-				    tar->sparse_offset, tar->sparse_numbytes);
++				if (gnu_add_sparse_entry(a, tar,
++				    tar->sparse_offset, tar->sparse_numbytes)
++				    != ARCHIVE_OK)
++					return (ARCHIVE_FATAL);
+ 				tar->sparse_offset = -1;
+ 				tar->sparse_numbytes = -1;
+ 			}
+@@ -1438,7 +1445,7 @@ pax_attribute(struct tar *tar, struct ar
+ 		if (strcmp(key, "GNU.sparse.map") == 0) {
+ 			tar->sparse_gnu_major = 0;
+ 			tar->sparse_gnu_minor = 1;
+-			if (gnu_sparse_01_parse(tar, value) != ARCHIVE_OK)
++			if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK)
+ 				return (ARCHIVE_WARN);
+ 		}
+ 
+@@ -1716,7 +1723,8 @@ header_gnutar(struct archive_read *a, st
+ 	}
+ 
+ 	if (header->sparse[0].offset[0] != 0) {
+-		gnu_sparse_old_read(a, tar, header);
++		if (gnu_sparse_old_read(a, tar, header) != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 	} else {
+ 		if (header->isextended[0] != 0) {
+ 			/* XXX WTF? XXX */
+@@ -1726,14 +1734,17 @@ header_gnutar(struct archive_read *a, st
+ 	return (0);
+ }
+ 
+-static void
+-gnu_add_sparse_entry(struct tar *tar, off_t offset, off_t remaining)
++static int
++gnu_add_sparse_entry(struct archive_read *a, struct tar *tar, off_t offset,
++	off_t remaining)
+ {
+ 	struct sparse_block *p;
+ 
+ 	p = (struct sparse_block *)malloc(sizeof(*p));
+-	if (p == NULL)
+-		__archive_errx(1, "Out of memory");
++	if (p == NULL) {
++		archive_set_error(&a->archive, ENOMEM, "Out of memory");
++		return (ARCHIVE_FATAL);
++	}
+ 	memset(p, 0, sizeof(*p));
+ 	if (tar->sparse_last != NULL)
+ 		tar->sparse_last->next = p;
+@@ -1742,6 +1753,7 @@ gnu_add_sparse_entry(struct tar *tar, of
+ 	tar->sparse_last = p;
+ 	p->offset = offset;
+ 	p->remaining = remaining;
++	return (ARCHIVE_OK);
+ }
+ 
+ static void
+@@ -1782,7 +1794,8 @@ gnu_sparse_old_read(struct archive_read
+ 	};
+ 	const struct extended *ext;
+ 
+-	gnu_sparse_old_parse(tar, header->sparse, 4);
++	if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK)
++		return (ARCHIVE_FATAL);
+ 	if (header->isextended[0] == 0)
+ 		return (ARCHIVE_OK);
+ 
+@@ -1798,24 +1811,28 @@ gnu_sparse_old_read(struct archive_read
+ 		}
+ 		__archive_read_consume(a, 512);
+ 		ext = (const struct extended *)data;
+-		gnu_sparse_old_parse(tar, ext->sparse, 21);
++		if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 	} while (ext->isextended[0] != 0);
+ 	if (tar->sparse_list != NULL)
+ 		tar->entry_offset = tar->sparse_list->offset;
+ 	return (ARCHIVE_OK);
+ }
+ 
+-static void
+-gnu_sparse_old_parse(struct tar *tar,
++static int
++gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
+     const struct gnu_sparse *sparse, int length)
+ {
+ 	while (length > 0 && sparse->offset[0] != 0) {
+-		gnu_add_sparse_entry(tar,
++		if (gnu_add_sparse_entry(a, tar,
+ 		    tar_atol(sparse->offset, sizeof(sparse->offset)),
+-		    tar_atol(sparse->numbytes, sizeof(sparse->numbytes)));
++		    tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
++		    != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 		sparse++;
+ 		length--;
+ 	}
++	return (ARCHIVE_OK);
+ }
+ 
+ /*
+@@ -1845,7 +1862,7 @@ gnu_sparse_old_parse(struct tar *tar,
+  */
+ 
+ static int
+-gnu_sparse_01_parse(struct tar *tar, const char *p)
++gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
+ {
+ 	const char *e;
+ 	off_t offset = -1, size = -1;
+@@ -1865,7 +1882,9 @@ gnu_sparse_01_parse(struct tar *tar, con
+ 			size = tar_atol10(p, e - p);
+ 			if (size < 0)
+ 				return (ARCHIVE_WARN);
+-			gnu_add_sparse_entry(tar, offset, size);
++			if (gnu_add_sparse_entry(a, tar, offset, size)
++			    != ARCHIVE_OK)
++				return (ARCHIVE_FATAL);
+ 			offset = -1;
+ 		}
+ 		if (*e == '\0')
+@@ -1969,7 +1988,8 @@ gnu_sparse_10_read(struct archive_read *
+ 		if (size < 0)
+ 			return (ARCHIVE_FATAL);
+ 		/* Add a new sparse entry. */
+-		gnu_add_sparse_entry(tar, offset, size);
++		if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK)
++			return (ARCHIVE_FATAL);
+ 	}
+ 	/* Skip rest of block... */
+ 	bytes_read = tar->entry_bytes_remaining - remaining;
diff --git a/libarchive.spec b/libarchive.spec
index 962a151..4c5c649 100644
--- a/libarchive.spec
+++ b/libarchive.spec
@@ -1,6 +1,6 @@
 Name:           libarchive
 Version:        2.8.4
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        A library for handling streaming archive formats 
 
 Group:          System Environment/Libraries
@@ -26,6 +26,10 @@ BuildRequires: libxml2-devel
 # https://bugzilla.redhat.com/show_bug.cgi?id=597243
 Patch0: libarchive-2.8.4-iso9660-data-types.patch
 
+# Bug 773505: CVE-2011-1777 and CVE-2011-1778
+Patch1: libarchive-2.8.4-CVE-2011-1777.patch
+Patch2: libarchive-2.8.4-CVE-2011-1778-2.patch
+
 
 %description
 Libarchive is a programming library that can create and read several different 
@@ -46,6 +50,8 @@ developing applications that use %{name}.
 %prep
 %setup -q
 %patch0 -p0 -b .iso9660-testsuite
+%patch1 -p1 -b .cve-2011-1777
+%patch2 -p1 -b .cve-2011-1778
 
 
 %build
@@ -88,6 +94,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sat Jan 14 2012 Niels de Vos <devos at fedoraproject.org> - 2.8.4-4
+- Security fixes (CVE-2011-1777, CVE-2011-1778) (#773505)
+
 * Mon Feb 07 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.8.4-3
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
 


More information about the scm-commits mailing list