Commit | Line | Data |
---|---|---|
b38e97e0 LF |
1 | Fix buffer overflow reading 7Zip files: |
2 | ||
3 | https://github.com/libarchive/libarchive/issues/761 | |
4 | ||
5 | Patch copied from upstream repository: | |
6 | ||
7 | https://github.com/libarchive/libarchive/commit/7f17c791dcfd8c0416e2cd2485b19410e47ef126 | |
8 | ||
9 | From 7f17c791dcfd8c0416e2cd2485b19410e47ef126 Mon Sep 17 00:00:00 2001 | |
10 | From: Tim Kientzle <kientzle@acm.org> | |
11 | Date: Sun, 18 Sep 2016 18:14:58 -0700 | |
12 | Subject: [PATCH] Issue 761: Heap overflow reading corrupted 7Zip files | |
13 | ||
14 | The sample file that demonstrated this had multiple 'EmptyStream' | |
15 | attributes. The first one ended up being used to calculate | |
16 | certain statistics, then was overwritten by the second which | |
17 | was incompatible with those statistics. | |
18 | ||
19 | The fix here is to reject any header with multiple EmptyStream | |
20 | attributes. While here, also reject headers with multiple | |
21 | EmptyFile, AntiFile, Name, or Attributes markers. | |
22 | --- | |
23 | libarchive/archive_read_support_format_7zip.c | 10 ++++++++++ | |
24 | 1 file changed, 10 insertions(+) | |
25 | ||
26 | diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c | |
27 | index 1dfe52b..c0a536c 100644 | |
28 | --- a/libarchive/archive_read_support_format_7zip.c | |
29 | +++ b/libarchive/archive_read_support_format_7zip.c | |
30 | @@ -2431,6 +2431,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h, | |
31 | ||
32 | switch (type) { | |
33 | case kEmptyStream: | |
34 | + if (h->emptyStreamBools != NULL) | |
35 | + return (-1); | |
36 | h->emptyStreamBools = calloc((size_t)zip->numFiles, | |
37 | sizeof(*h->emptyStreamBools)); | |
38 | if (h->emptyStreamBools == NULL) | |
39 | @@ -2451,6 +2453,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h, | |
40 | return (-1); | |
41 | break; | |
42 | } | |
43 | + if (h->emptyFileBools != NULL) | |
44 | + return (-1); | |
45 | h->emptyFileBools = calloc(empty_streams, | |
46 | sizeof(*h->emptyFileBools)); | |
47 | if (h->emptyFileBools == NULL) | |
48 | @@ -2465,6 +2469,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h, | |
49 | return (-1); | |
50 | break; | |
51 | } | |
52 | + if (h->antiBools != NULL) | |
53 | + return (-1); | |
54 | h->antiBools = calloc(empty_streams, | |
55 | sizeof(*h->antiBools)); | |
56 | if (h->antiBools == NULL) | |
57 | @@ -2491,6 +2497,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h, | |
58 | if ((ll & 1) || ll < zip->numFiles * 4) | |
59 | return (-1); | |
60 | ||
61 | + if (zip->entry_names != NULL) | |
62 | + return (-1); | |
63 | zip->entry_names = malloc(ll); | |
64 | if (zip->entry_names == NULL) | |
65 | return (-1); | |
66 | @@ -2543,6 +2551,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h, | |
67 | if ((p = header_bytes(a, 2)) == NULL) | |
68 | return (-1); | |
69 | allAreDefined = *p; | |
70 | + if (h->attrBools != NULL) | |
71 | + return (-1); | |
72 | h->attrBools = calloc((size_t)zip->numFiles, | |
73 | sizeof(*h->attrBools)); | |
74 | if (h->attrBools == NULL) | |
75 | -- | |
76 | 2.10.0 | |
77 |