Mercurial > vanilla
comparison compression/unzip/CVE-2014-8141.patch @ 452:8c4366128400
compression/unzip: initial import, closes #1553
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 06 Apr 2019 08:13:23 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
451:bcfdaa03daa2 | 452:8c4366128400 |
---|---|
1 From RedHat: https://bugzilla.redhat.com/attachment.cgi?id=969625&action=diff | |
2 (unzip60/ path prefix added) | |
3 | |
4 --- unzip60/process.c 2009-03-06 02:25:10.000000000 +0100 | |
5 +++ unzip60/process.c 2014-12-05 22:42:39.000000000 +0100 | |
6 @@ -1,5 +1,5 @@ | |
7 /* | |
8 - Copyright (c) 1990-2009 Info-ZIP. All rights reserved. | |
9 + Copyright (c) 1990-2014 Info-ZIP. All rights reserved. | |
10 | |
11 See the accompanying file LICENSE, version 2009-Jan-02 or later | |
12 (the contents of which are also included in unzip.h) for terms of use. | |
13 @@ -1888,48 +1888,82 @@ int getZip64Data(__G__ ef_buf, ef_len) | |
14 and a 4-byte version of disk start number. | |
15 Sets both local header and central header fields. Not terribly clever, | |
16 but it means that this procedure is only called in one place. | |
17 + | |
18 + 2014-12-05 SMS. | |
19 + Added checks to ensure that enough data are available before calling | |
20 + makeint64() or makelong(). Replaced various sizeof() values with | |
21 + simple ("4" or "8") constants. (The Zip64 structures do not depend | |
22 + on our variable sizes.) Error handling is crude, but we should now | |
23 + stay within the buffer. | |
24 ---------------------------------------------------------------------------*/ | |
25 | |
26 +#define Z64FLGS 0xffff | |
27 +#define Z64FLGL 0xffffffff | |
28 + | |
29 if (ef_len == 0 || ef_buf == NULL) | |
30 return PK_COOL; | |
31 | |
32 Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n", | |
33 ef_len)); | |
34 | |
35 - while (ef_len >= EB_HEADSIZE) { | |
36 + while (ef_len >= EB_HEADSIZE) | |
37 + { | |
38 eb_id = makeword(EB_ID + ef_buf); | |
39 eb_len = makeword(EB_LEN + ef_buf); | |
40 | |
41 - if (eb_len > (ef_len - EB_HEADSIZE)) { | |
42 - /* discovered some extra field inconsistency! */ | |
43 + if (eb_len > (ef_len - EB_HEADSIZE)) | |
44 + { | |
45 + /* Extra block length exceeds remaining extra field length. */ | |
46 Trace((stderr, | |
47 "getZip64Data: block length %u > rest ef_size %u\n", eb_len, | |
48 ef_len - EB_HEADSIZE)); | |
49 break; | |
50 } | |
51 - if (eb_id == EF_PKSZ64) { | |
52 - | |
53 + if (eb_id == EF_PKSZ64) | |
54 + { | |
55 int offset = EB_HEADSIZE; | |
56 | |
57 - if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){ | |
58 - G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf); | |
59 - offset += sizeof(G.crec.ucsize); | |
60 + if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL)) | |
61 + { | |
62 + if (offset+ 8 > ef_len) | |
63 + return PK_ERR; | |
64 + | |
65 + G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf); | |
66 + offset += 8; | |
67 } | |
68 - if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){ | |
69 - G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf); | |
70 - offset += sizeof(G.crec.csize); | |
71 + | |
72 + if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL)) | |
73 + { | |
74 + if (offset+ 8 > ef_len) | |
75 + return PK_ERR; | |
76 + | |
77 + G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf); | |
78 + offset += 8; | |
79 } | |
80 - if (G.crec.relative_offset_local_header == 0xffffffff){ | |
81 + | |
82 + if (G.crec.relative_offset_local_header == Z64FLGL) | |
83 + { | |
84 + if (offset+ 8 > ef_len) | |
85 + return PK_ERR; | |
86 + | |
87 G.crec.relative_offset_local_header = makeint64(offset + ef_buf); | |
88 - offset += sizeof(G.crec.relative_offset_local_header); | |
89 + offset += 8; | |
90 } | |
91 - if (G.crec.disk_number_start == 0xffff){ | |
92 + | |
93 + if (G.crec.disk_number_start == Z64FLGS) | |
94 + { | |
95 + if (offset+ 4 > ef_len) | |
96 + return PK_ERR; | |
97 + | |
98 G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf); | |
99 - offset += sizeof(G.crec.disk_number_start); | |
100 + offset += 4; | |
101 } | |
102 +#if 0 | |
103 + break; /* Expect only one EF_PKSZ64 block. */ | |
104 +#endif /* 0 */ | |
105 } | |
106 | |
107 - /* Skip this extra field block */ | |
108 + /* Skip this extra field block. */ | |
109 ef_buf += (eb_len + EB_HEADSIZE); | |
110 ef_len -= (eb_len + EB_HEADSIZE); | |
111 } | |
112 --- unzip60/fileio.c 2009-04-20 02:03:44.000000000 +0200 | |
113 +++ unzip60/fileio.c 2014-12-05 22:44:16.000000000 +0100 | |
114 @@ -176,6 +176,8 @@ static ZCONST char Far FilenameTooLongTr | |
115 #endif | |
116 static ZCONST char Far ExtraFieldTooLong[] = | |
117 "warning: extra field too long (%d). Ignoring...\n"; | |
118 +static ZCONST char Far ExtraFieldCorrupt[] = | |
119 + "warning: extra field (type: 0x%04x) corrupt. Continuing...\n"; | |
120 | |
121 #ifdef WINDLL | |
122 static ZCONST char Far DiskFullQuery[] = | |
123 @@ -2295,7 +2297,12 @@ int do_string(__G__ length, option) /* | |
124 if (readbuf(__G__ (char *)G.extra_field, length) == 0) | |
125 return PK_EOF; | |
126 /* Looks like here is where extra fields are read */ | |
127 - getZip64Data(__G__ G.extra_field, length); | |
128 + if (getZip64Data(__G__ G.extra_field, length) != PK_COOL) | |
129 + { | |
130 + Info(slide, 0x401, ((char *)slide, | |
131 + LoadFarString( ExtraFieldCorrupt), EF_PKSZ64)); | |
132 + error = PK_WARN; | |
133 + } | |
134 #ifdef UNICODE_SUPPORT | |
135 G.unipath_filename = NULL; | |
136 if (G.UzO.U_flag < 2) { |