Skip to content

Commit

Permalink
Issue 761: Heap overflow reading corrupted 7Zip files
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kientzle committed Sep 19, 2016
1 parent a6dd4cc commit 7f17c79
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions libarchive/archive_read_support_format_7zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 7f17c79

Please sign in to comment.