summaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_7zip.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@acm.org>2016-09-18 18:14:58 -0700
committerTim Kientzle <kientzle@acm.org>2016-09-18 18:14:58 -0700
commit7f17c791dcfd8c0416e2cd2485b19410e47ef126 (patch)
tree81591383f4fe2f402beee3c3d74f6eee1abd35ba /libarchive/archive_read_support_format_7zip.c
parenta6dd4cc26217b9302dad59d1fcd4f5114abc10af (diff)
downloadlibarchive-7f17c791dcfd8c0416e2cd2485b19410e47ef126.tar.gz
Issue 761: Heap overflow reading corrupted 7Zip files
The sample file that demonstrated this had multiple 'EmptyStream' attributes. The first one ended up being used to calculate certain statistics, then was overwritten by the second which was incompatible with those statistics. The fix here is to reject any header with multiple EmptyStream attributes. While here, also reject headers with multiple EmptyFile, AntiFile, Name, or Attributes markers.
Diffstat (limited to 'libarchive/archive_read_support_format_7zip.c')
-rw-r--r--libarchive/archive_read_support_format_7zip.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
index 1dfe52b8..c0a536c4 100644
--- a/libarchive/archive_read_support_format_7zip.c
+++ b/libarchive/archive_read_support_format_7zip.c
@@ -2431,6 +2431,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
switch (type) {
case kEmptyStream:
+ if (h->emptyStreamBools != NULL)
+ return (-1);
h->emptyStreamBools = calloc((size_t)zip->numFiles,
sizeof(*h->emptyStreamBools));
if (h->emptyStreamBools == NULL)
@@ -2451,6 +2453,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
return (-1);
break;
}
+ if (h->emptyFileBools != NULL)
+ return (-1);
h->emptyFileBools = calloc(empty_streams,
sizeof(*h->emptyFileBools));
if (h->emptyFileBools == NULL)
@@ -2465,6 +2469,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
return (-1);
break;
}
+ if (h->antiBools != NULL)
+ return (-1);
h->antiBools = calloc(empty_streams,
sizeof(*h->antiBools));
if (h->antiBools == NULL)
@@ -2491,6 +2497,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if ((ll & 1) || ll < zip->numFiles * 4)
return (-1);
+ if (zip->entry_names != NULL)
+ return (-1);
zip->entry_names = malloc(ll);
if (zip->entry_names == NULL)
return (-1);
@@ -2543,6 +2551,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if ((p = header_bytes(a, 2)) == NULL)
return (-1);
allAreDefined = *p;
+ if (h->attrBools != NULL)
+ return (-1);
h->attrBools = calloc((size_t)zip->numFiles,
sizeof(*h->attrBools));
if (h->attrBools == NULL)