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) {