summaryrefslogtreecommitdiff
path: root/archivers
diff options
context:
space:
mode:
authorhe <he>2014-04-03 13:05:14 +0000
committerhe <he>2014-04-03 13:05:14 +0000
commit681fed965a32fbd28c7878d1b76e24ad74da01d6 (patch)
tree9a71c9e5b145c29ed1f4441445ee0a3488cad3eb /archivers
parente10b3fc943a5d5a626dcc25893818dff5bd88882 (diff)
downloadpkgsrc-681fed965a32fbd28c7878d1b76e24ad74da01d6.tar.gz
Apply fixes for CVE-2011-1777 and CVE-2011-1778 (add check for
buffer overflows in handling iso9660 and tar images), despite Joerg telling me I should have better things to spend my time on. Fixes pulled from https://bugzilla.redhat.com/show_bug.cgi?id=705849 Bump PKGREVISION.
Diffstat (limited to 'archivers')
-rw-r--r--archivers/libarchive/Makefile6
-rw-r--r--archivers/libarchive/files/libarchive/archive_read_support_format_iso9660.c65
-rw-r--r--archivers/libarchive/files/libarchive/archive_read_support_format_tar.c76
3 files changed, 94 insertions, 53 deletions
diff --git a/archivers/libarchive/Makefile b/archivers/libarchive/Makefile
index 321ae4db944..09152775477 100644
--- a/archivers/libarchive/Makefile
+++ b/archivers/libarchive/Makefile
@@ -1,14 +1,14 @@
-# $NetBSD: Makefile,v 1.39 2014/02/12 23:17:32 tron Exp $
+# $NetBSD: Makefile,v 1.40 2014/04/03 13:05:14 he Exp $
#
DISTNAME= libarchive-2.8.4
-PKGREVISION= 3
+PKGREVISION= 4
CATEGORIES= archivers
MASTER_SITES= # empty
DISTFILES= # empty
MAINTAINER= joerg@NetBSD.org
-HOMEPAGE= http://code.google.com/p/libarchive/
+HOMEPAGE= http://www.libarchive.org/
COMMENT= Library to read/create different archive formats
GNU_CONFIGURE= yes
diff --git a/archivers/libarchive/files/libarchive/archive_read_support_format_iso9660.c b/archivers/libarchive/files/libarchive/archive_read_support_format_iso9660.c
index 0c640c88e86..65988ca4fd4 100644
--- a/archivers/libarchive/files/libarchive/archive_read_support_format_iso9660.c
+++ b/archivers/libarchive/files/libarchive/archive_read_support_format_iso9660.c
@@ -405,12 +405,12 @@ static inline void cache_add_entry(struct iso9660 *iso9660,
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 @@ read_children(struct archive_read *a, struct file_info *parent)
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 @@ read_children(struct archive_read *a, struct file_info *parent)
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 @@ read_children(struct archive_read *a, struct file_info *parent)
}
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 @@ relocate_dir(struct iso9660 *iso9660, struct file_info *file)
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 @@ read_entries(struct archive_read *a)
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 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
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,9 @@ cache_get_entry(struct iso9660 *iso9660)
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 +2646,18 @@ heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
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 +2684,8 @@ heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
hole = parent;
}
heap->files[0] = file;
+
+ return (ARCHIVE_OK);
}
static struct file_info *
diff --git a/archivers/libarchive/files/libarchive/archive_read_support_format_tar.c b/archivers/libarchive/files/libarchive/archive_read_support_format_tar.c
index dae13dc6e00..d06b18d8da1 100644
--- a/archivers/libarchive/files/libarchive/archive_read_support_format_tar.c
+++ b/archivers/libarchive/files/libarchive/archive_read_support_format_tar.c
@@ -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 *, 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(struct archive_read *a);
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(struct archive_read *a,
* 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, struct tar *tar,
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 *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 archive_entry *entry,
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 archive_entry *entry,
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 archive_entry *entry,
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, struct tar *tar,
}
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, struct tar *tar,
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, off_t offset, off_t remaining)
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 *a, struct tar *tar,
};
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 *a, struct tar *tar,
}
__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, const char *p)
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 *a, struct tar *tar)
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;