瀏覽代碼

unzip: patch CVE-2014-8139, CVE-2014-8140, CVE-2014-8141 and CVE-2014-9636

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Álvaro Fernández Rojas 10 年之前
父節點
當前提交
857def5d1a

+ 2
- 2
utils/unzip/Makefile 查看文件

@@ -1,5 +1,5 @@
1 1
 #
2
-# Copyright (C) 2006-2014 OpenWrt.org
2
+# Copyright (C) 2006-2015 OpenWrt.org
3 3
 #
4 4
 # This is free software, licensed under the GNU General Public License v2.
5 5
 # See /LICENSE for more information.
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
10 10
 PKG_NAME:=unzip
11 11
 PKG_REV:=60
12 12
 PKG_VERSION:=6.0
13
-PKG_RELEASE:=1
13
+PKG_RELEASE:=2
14 14
 
15 15
 PKG_SOURCE:=$(PKG_NAME)$(PKG_REV).tar.gz
16 16
 PKG_SOURCE_URL:=@SF/infozip

+ 49
- 0
utils/unzip/patches/001-CVE-2014-8139-crc-overflow.patch 查看文件

@@ -0,0 +1,49 @@
1
+--- a/extract.c
2
++++ b/extract.c
3
+@@ -1,5 +1,5 @@
4
+ /*
5
+-  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
6
++  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
7
+ 
8
+   See the accompanying file LICENSE, version 2009-Jan-02 or later
9
+   (the contents of which are also included in unzip.h) for terms of use.
10
+@@ -298,6 +298,8 @@ char ZCONST Far TruncNTSD[] =
11
+ #ifndef SFX
12
+    static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
13
+      EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
14
++   static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
15
++     EF block length (%u bytes) invalid (< %d)\n";
16
+    static ZCONST char Far InvalidComprDataEAs[] =
17
+      " invalid compressed data for EAs\n";
18
+ #  if (defined(WIN32) && defined(NTSD_EAS))
19
+@@ -2023,7 +2025,8 @@ static int TestExtraField(__G__ ef, ef_l
20
+         ebID = makeword(ef);
21
+         ebLen = (unsigned)makeword(ef+EB_LEN);
22
+ 
23
+-        if (ebLen > (ef_len - EB_HEADSIZE)) {
24
++        if (ebLen > (ef_len - EB_HEADSIZE))
25
++        {
26
+            /* Discovered some extra field inconsistency! */
27
+             if (uO.qflag)
28
+                 Info(slide, 1, ((char *)slide, "%-22s ",
29
+@@ -2158,11 +2161,19 @@ static int TestExtraField(__G__ ef, ef_l
30
+                 }
31
+                 break;
32
+             case EF_PKVMS:
33
+-                if (makelong(ef+EB_HEADSIZE) !=
34
++                if (ebLen < 4)
35
++                {
36
++                    Info(slide, 1,
37
++                     ((char *)slide, LoadFarString(TooSmallEBlength),
38
++                     ebLen, 4));
39
++                }
40
++                else if (makelong(ef+EB_HEADSIZE) !=
41
+                     crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
42
+                           (extent)(ebLen-4)))
43
++                {
44
+                     Info(slide, 1, ((char *)slide,
45
+                       LoadFarString(BadCRC_EAs)));
46
++                }
47
+                 break;
48
+             case EF_PKW32:
49
+             case EF_PKUNIX:

+ 23
- 0
utils/unzip/patches/002-CVE-2014-8140-test-compr-eb.patch 查看文件

@@ -0,0 +1,23 @@
1
+--- a/extract.c
2
++++ b/extract.c
3
+@@ -2232,10 +2232,17 @@ static int test_compr_eb(__G__ eb, eb_si
4
+     if (compr_offset < 4)                /* field is not compressed: */
5
+         return PK_OK;                    /* do nothing and signal OK */
6
+ 
7
++    /* Return no/bad-data error status if any problem is found:
8
++     *    1. eb_size is too small to hold the uncompressed size
9
++     *       (eb_ucsize).  (Else extract eb_ucsize.)
10
++     *    2. eb_ucsize is zero (invalid).  2014-12-04 SMS.
11
++     *    3. eb_ucsize is positive, but eb_size is too small to hold
12
++     *       the compressed data header.
13
++     */
14
+     if ((eb_size < (EB_UCSIZE_P + 4)) ||
15
+-        ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
16
+-         eb_size <= (compr_offset + EB_CMPRHEADLEN)))
17
+-        return IZ_EF_TRUNC;               /* no compressed data! */
18
++     ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
19
++     ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
20
++        return IZ_EF_TRUNC;             /* no/bad compressed data! */
21
+ 
22
+     if (
23
+ #ifdef INT_16BIT

+ 133
- 0
utils/unzip/patches/003-CVE-2014-8141-getzip64data.patch 查看文件

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

+ 25
- 0
utils/unzip/patches/004-CVE-2014-9636-test-compr-eb.patch 查看文件

@@ -0,0 +1,25 @@
1
+--- a/extract.c
2
++++ b/extract.c
3
+@@ -2228,6 +2228,7 @@ static int test_compr_eb(__G__ eb, eb_si
4
+     ulg eb_ucsize;
5
+     uch *eb_ucptr;
6
+     int r;
7
++    ush eb_compr_method;
8
+ 
9
+     if (compr_offset < 4)                /* field is not compressed: */
10
+         return PK_OK;                    /* do nothing and signal OK */
11
+@@ -2244,6 +2245,14 @@ static int test_compr_eb(__G__ eb, eb_si
12
+      ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
13
+         return IZ_EF_TRUNC;             /* no/bad compressed data! */
14
+ 
15
++    /* 2014-11-03 Michal Zalewski, SMS.
16
++     * For STORE method, compressed and uncompressed sizes must agree.
17
++     * http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=450
18
++     */
19
++    eb_compr_method = makeword( eb + (EB_HEADSIZE + compr_offset));
20
++    if ((eb_compr_method == STORED) && (eb_size - compr_offset != eb_ucsize))
21
++        return PK_ERR;
22
++
23
+     if (
24
+ #ifdef INT_16BIT
25
+         (((ulg)(extent)eb_ucsize) != eb_ucsize) ||