Pullup ticket #4855 - requested by he archivers/unzip: security fix Revisions pulled up: - archivers/unzip/Makefile 1.91 - archivers/unzip/distinfo 1.29 - archivers/unzip/patches/patch-crypt.c 1.1 - archivers/unzip/patches/patch-extract.c 1.3 --- Module Name: pkgsrc Committed By: wiz Date: Wed Nov 11 12:47:27 UTC 2015 Modified Files: pkgsrc/archivers/unzip: Makefile distinfo pkgsrc/archivers/unzip/patches: patch-extract.c Added Files: pkgsrc/archivers/unzip/patches: patch-crypt.c Log Message: Add patches to fix CVE-2015-7696, CVE-2015-7697, and an integer underflow. From Debian. Bump PKGREVISION.diff -r1.90 -r1.90.4.1 pkgsrc/archivers/unzip/Makefile
(bsiegert)
@@ -1,18 +1,18 @@ | @@ -1,18 +1,18 @@ | |||
1 | # $NetBSD: Makefile,v 1.90 2015/06/05 12:22:28 sevan Exp $ | 1 | # $NetBSD: Makefile,v 1.90.4.1 2015/11/20 21:05:34 bsiegert Exp $ | |
2 | 2 | |||
3 | DISTNAME= unzip60 | 3 | DISTNAME= unzip60 | |
4 | PKGNAME= unzip-6.0 | 4 | PKGNAME= unzip-6.0 | |
5 | PKGREVISION= 4 | 5 | PKGREVISION= 5 | |
6 | CATEGORIES= archivers | 6 | CATEGORIES= archivers | |
7 | MASTER_SITES= ftp://ftp.info-zip.org/pub/infozip/src/ | 7 | MASTER_SITES= ftp://ftp.info-zip.org/pub/infozip/src/ | |
8 | EXTRACT_SUFX= .tgz | 8 | EXTRACT_SUFX= .tgz | |
9 | 9 | |||
10 | MAINTAINER= wiz@NetBSD.org | 10 | MAINTAINER= wiz@NetBSD.org | |
11 | HOMEPAGE= http://www.info-zip.org/UnZip.html | 11 | HOMEPAGE= http://www.info-zip.org/UnZip.html | |
12 | COMMENT= List, test and extract compressed files in a ZIP archive | 12 | COMMENT= List, test and extract compressed files in a ZIP archive | |
13 | LICENSE= info-zip | 13 | LICENSE= info-zip | |
14 | 14 | |||
15 | REPLACE_SH= unix/zipgrep | 15 | REPLACE_SH= unix/zipgrep | |
16 | 16 | |||
17 | USE_TOOLS+= gmake | 17 | USE_TOOLS+= gmake | |
18 | 18 |
@@ -1,12 +1,13 @@ | @@ -1,12 +1,13 @@ | |||
1 | $NetBSD: distinfo,v 1.27 2015/02/11 12:35:42 wiz Exp $ | 1 | $NetBSD: distinfo,v 1.27.6.1 2015/11/20 21:05:34 bsiegert Exp $ | |
2 | 2 | |||
3 | SHA1 (unzip60.tgz) = abf7de8a4018a983590ed6f5cbd990d4740f8a22 | 3 | SHA1 (unzip60.tgz) = abf7de8a4018a983590ed6f5cbd990d4740f8a22 | |
4 | RMD160 (unzip60.tgz) = 48af66606e9472e45fbb94bc4e285da23d1b89ba | 4 | RMD160 (unzip60.tgz) = 48af66606e9472e45fbb94bc4e285da23d1b89ba | |
5 | Size (unzip60.tgz) = 1376845 bytes | 5 | Size (unzip60.tgz) = 1376845 bytes | |
6 | SHA1 (patch-ab) = 672635c469e0a53ac9808f8155ee38643a8acf69 | 6 | SHA1 (patch-ab) = 672635c469e0a53ac9808f8155ee38643a8acf69 | |
7 | SHA1 (patch-ac) = 27b91401d4d5ecc3842c91dc49c08f42c8646154 | 7 | SHA1 (patch-ac) = 27b91401d4d5ecc3842c91dc49c08f42c8646154 | |
8 | SHA1 (patch-extract.c) = bba436910084ec43ef8f8e76a1cd0392c566e4ac | 8 | SHA1 (patch-crypt.c) = e44e14ba2c8e5651659c6756a5adbe88b4385ca4 | |
9 | SHA1 (patch-extract.c) = 042fe7d233d0b3cb1e978902c901e8239f7a3732 | |||
9 | SHA1 (patch-fileio.c) = 910ddb3b847cae92326697a399234b2948555534 | 10 | SHA1 (patch-fileio.c) = 910ddb3b847cae92326697a399234b2948555534 | |
10 | SHA1 (patch-list.c) = 7aa261ecef5e5cc14ad387070560730ff419d635 | 11 | SHA1 (patch-list.c) = 7aa261ecef5e5cc14ad387070560730ff419d635 | |
11 | SHA1 (patch-process.c) = d6e6ed05ef7c2977353e848d9e9cba2877577812 | 12 | SHA1 (patch-process.c) = d6e6ed05ef7c2977353e848d9e9cba2877577812 | |
12 | SHA1 (patch-unix_unxcfg.h) = b2831f38b2245dacedd4eb2eef12ee1e3cf20613 | 13 | SHA1 (patch-unix_unxcfg.h) = b2831f38b2245dacedd4eb2eef12ee1e3cf20613 |
$NetBSD: patch-crypt.c,v 1.1.2.2 2015/11/20 21:05:34 bsiegert Exp $
Bug fix for heap overflow, from Debian.
CVE-2015-7696
--- crypt.c.orig 2007-01-05 15:47:36.000000000 +0000
+++ crypt.c
@@ -465,7 +465,17 @@ int decrypt(__G__ passwrd)
GLOBAL(pInfo->encrypted) = FALSE;
defer_leftover_input(__G);
for (n = 0; n < RAND_HEAD_LEN; n++) {
- b = NEXTBYTE;
+ /* 2012-11-23 SMS. (OUSPG report.)
+ * Quit early if compressed size < HEAD_LEN. The resulting
+ * error message ("unable to get password") could be improved,
+ * but it's better than trying to read nonexistent data, and
+ * then continuing with a negative G.csize. (See
+ * fileio.c:readbyte()).
+ */
+ if ((b = NEXTBYTE) == (ush)EOF)
+ {
+ return PK_ERR;
+ }
h[n] = (uch)b;
Trace((stdout, " (%02x)", h[n]));
}
@@ -1,87 +1,123 @@ | @@ -1,87 +1,123 @@ | |||
1 | $NetBSD: patch-extract.c,v 1.2 2015/02/11 12:35:42 wiz Exp $ | 1 | $NetBSD: patch-extract.c,v 1.2.6.1 2015/11/20 21:05:34 bsiegert Exp $ | |
2 | 2 | |||
3 | Fixes for | 3 | Fixes for | |
4 | * https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-8139 | 4 | * https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-8139 | |
5 | * https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-8140 | 5 | * https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-8140 | |
6 | * http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow2.diff via | 6 | * http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow2.diff via | |
7 | http://seclists.org/oss-sec/2014/q4/1131 and | 7 | http://seclists.org/oss-sec/2014/q4/1131 and | |
8 | http://seclists.org/oss-sec/2014/q4/507 and later version | 8 | http://seclists.org/oss-sec/2014/q4/507 and later version | |
9 | http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow3.diff via | 9 | http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow3.diff via | |
10 | http://www.openwall.com/lists/oss-security/2015/02/11/7 | 10 | http://www.openwall.com/lists/oss-security/2015/02/11/7 | |
11 | 11 | |||
12 | By carefully crafting a corrupt ZIP archive with "extra fields" that | 12 | By carefully crafting a corrupt ZIP archive with "extra fields" that | |
13 | purport to have compressed blocks larger than the corresponding | 13 | purport to have compressed blocks larger than the corresponding | |
14 | uncompressed blocks in STORED no-compression mode, an attacker can | 14 | uncompressed blocks in STORED no-compression mode, an attacker can | |
15 | trigger a heap overflow that can result in application crash or | 15 | trigger a heap overflow that can result in application crash or | |
16 | possibly have other unspecified impact. | 16 | possibly have other unspecified impact. | |
17 | 17 | |||
18 | This patch ensures that when extra fields use STORED mode, the | 18 | This patch ensures that when extra fields use STORED mode, the | |
19 | "compressed" and uncompressed block sizes match. | 19 | "compressed" and uncompressed block sizes match. | |
20 | * CVE-2015-7697 (from Debian) | |||
21 | https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802160 | |||
22 | * integer underflow | |||
23 | https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802160 | |||
20 | 24 | |||
21 | --- extract.c.orig 2009-03-14 01:32:52.000000000 +0000 | 25 | --- extract.c.orig 2009-03-14 01:32:52.000000000 +0000 | |
22 | +++ extract.c | 26 | +++ extract.c | |
23 | @@ -1,5 +1,5 @@ | 27 | @@ -1,5 +1,5 @@ | |
24 | /* | 28 | /* | |
25 | - Copyright (c) 1990-2009 Info-ZIP. All rights reserved. | 29 | - Copyright (c) 1990-2009 Info-ZIP. All rights reserved. | |
26 | + Copyright (c) 1990-2014 Info-ZIP. All rights reserved. | 30 | + Copyright (c) 1990-2014 Info-ZIP. All rights reserved. | |
27 | 31 | |||
28 | See the accompanying file LICENSE, version 2009-Jan-02 or later | 32 | See the accompanying file LICENSE, version 2009-Jan-02 or later | |
29 | (the contents of which are also included in unzip.h) for terms of use. | 33 | (the contents of which are also included in unzip.h) for terms of use. | |
30 | @@ -298,6 +298,8 @@ char ZCONST Far TruncNTSD[] = | 34 | @@ -298,6 +298,8 @@ char ZCONST Far TruncNTSD[] = | |
31 | #ifndef SFX | 35 | #ifndef SFX | |
32 | static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \ | 36 | static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \ | |
33 | EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n"; | 37 | EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n"; | |
34 | + static ZCONST char Far TooSmallEFlength[] = "bad extra-field entry:\n \ | 38 | + static ZCONST char Far TooSmallEFlength[] = "bad extra-field entry:\n \ | |
35 | + EF block length (%u bytes) invalid (< %d)\n"; | 39 | + EF block length (%u bytes) invalid (< %d)\n"; | |
36 | static ZCONST char Far InvalidComprDataEAs[] = | 40 | static ZCONST char Far InvalidComprDataEAs[] = | |
37 | " invalid compressed data for EAs\n"; | 41 | " invalid compressed data for EAs\n"; | |
38 | # if (defined(WIN32) && defined(NTSD_EAS)) | 42 | # if (defined(WIN32) && defined(NTSD_EAS)) | |
39 | @@ -2023,7 +2025,8 @@ static int TestExtraField(__G__ ef, ef_l | 43 | @@ -1255,8 +1257,17 @@ static int extract_or_test_entrylist(__G | |
44 | if (G.lrec.compression_method == STORED) { | |||
45 | zusz_t csiz_decrypted = G.lrec.csize; | |||
46 | ||||
47 | - if (G.pInfo->encrypted) | |||
48 | + if (G.pInfo->encrypted) { | |||
49 | + if (csiz_decrypted <= 12) { | |||
50 | + /* handle the error now to prevent unsigned overflow */ | |||
51 | + Info(slide, 0x401, ((char *)slide, | |||
52 | + LoadFarStringSmall(ErrUnzipNoFile), | |||
53 | + LoadFarString(InvalidComprData), | |||
54 | + LoadFarStringSmall2(Inflate))); | |||
55 | + return PK_ERR; | |||
56 | + } | |||
57 | csiz_decrypted -= 12; | |||
58 | + } | |||
59 | if (G.lrec.ucsize != csiz_decrypted) { | |||
60 | Info(slide, 0x401, ((char *)slide, | |||
61 | LoadFarStringSmall2(WrnStorUCSizCSizDiff), | |||
62 | @@ -2023,7 +2034,8 @@ static int TestExtraField(__G__ ef, ef_l | |||
40 | ebID = makeword(ef); | 63 | ebID = makeword(ef); | |
41 | ebLen = (unsigned)makeword(ef+EB_LEN); | 64 | ebLen = (unsigned)makeword(ef+EB_LEN); | |
42 | 65 | |||
43 | - if (ebLen > (ef_len - EB_HEADSIZE)) { | 66 | - if (ebLen > (ef_len - EB_HEADSIZE)) { | |
44 | + if (ebLen > (ef_len - EB_HEADSIZE)) | 67 | + if (ebLen > (ef_len - EB_HEADSIZE)) | |
45 | + { | 68 | + { | |
46 | /* Discovered some extra field inconsistency! */ | 69 | /* Discovered some extra field inconsistency! */ | |
47 | if (uO.qflag) | 70 | if (uO.qflag) | |
48 | Info(slide, 1, ((char *)slide, "%-22s ", | 71 | Info(slide, 1, ((char *)slide, "%-22s ", | |
49 | @@ -2032,6 +2035,16 @@ static int TestExtraField(__G__ ef, ef_l | 72 | @@ -2032,6 +2044,16 @@ static int TestExtraField(__G__ ef, ef_l | |
50 | ebLen, (ef_len - EB_HEADSIZE))); | 73 | ebLen, (ef_len - EB_HEADSIZE))); | |
51 | return PK_ERR; | 74 | return PK_ERR; | |
52 | } | 75 | } | |
53 | + else if (ebLen < EB_HEADSIZE) | 76 | + else if (ebLen < EB_HEADSIZE) | |
54 | + { | 77 | + { | |
55 | + /* Extra block length smaller than header length. */ | 78 | + /* Extra block length smaller than header length. */ | |
56 | + if (uO.qflag) | 79 | + if (uO.qflag) | |
57 | + Info(slide, 1, ((char *)slide, "%-22s ", | 80 | + Info(slide, 1, ((char *)slide, "%-22s ", | |
58 | + FnFilter1(G.filename))); | 81 | + FnFilter1(G.filename))); | |
59 | + Info(slide, 1, ((char *)slide, LoadFarString(TooSmallEFlength), | 82 | + Info(slide, 1, ((char *)slide, LoadFarString(TooSmallEFlength), | |
60 | + ebLen, EB_HEADSIZE)); | 83 | + ebLen, EB_HEADSIZE)); | |
61 | + return PK_ERR; | 84 | + return PK_ERR; | |
62 | + } | 85 | + } | |
63 | 86 | |||
64 | switch (ebID) { | 87 | switch (ebID) { | |
65 | case EF_OS2: | 88 | case EF_OS2: | |
66 | @@ -2217,6 +2230,7 @@ static int test_compr_eb(__G__ eb, eb_si | 89 | @@ -2217,6 +2239,7 @@ static int test_compr_eb(__G__ eb, eb_si | |
67 | ulg eb_ucsize; | 90 | ulg eb_ucsize; | |
68 | uch *eb_ucptr; | 91 | uch *eb_ucptr; | |
69 | int r; | 92 | int r; | |
70 | + ush method; | 93 | + ush method; | |
71 | 94 | |||
72 | if (compr_offset < 4) /* field is not compressed: */ | 95 | if (compr_offset < 4) /* field is not compressed: */ | |
73 | return PK_OK; /* do nothing and signal OK */ | 96 | return PK_OK; /* do nothing and signal OK */ | |
74 | @@ -2226,6 +2240,13 @@ static int test_compr_eb(__G__ eb, eb_si | 97 | @@ -2226,6 +2249,13 @@ static int test_compr_eb(__G__ eb, eb_si | |
75 | eb_size <= (compr_offset + EB_CMPRHEADLEN))) | 98 | eb_size <= (compr_offset + EB_CMPRHEADLEN))) | |
76 | return IZ_EF_TRUNC; /* no compressed data! */ | 99 | return IZ_EF_TRUNC; /* no compressed data! */ | |
77 | 100 | |||
78 | + method = makeword(eb + (EB_HEADSIZE + compr_offset)); | 101 | + method = makeword(eb + (EB_HEADSIZE + compr_offset)); | |
79 | + if ((method == STORED) && | 102 | + if ((method == STORED) && | |
80 | + (eb_size - compr_offset - EB_CMPRHEADLEN != eb_ucsize)) | 103 | + (eb_size - compr_offset - EB_CMPRHEADLEN != eb_ucsize)) | |
81 | + return PK_ERR; /* compressed & uncompressed | 104 | + return PK_ERR; /* compressed & uncompressed | |
82 | + * should match in STORED | 105 | + * should match in STORED | |
83 | + * method */ | 106 | + * method */ | |
84 | + | 107 | + | |
85 | if ( | 108 | if ( | |
86 | #ifdef INT_16BIT | 109 | #ifdef INT_16BIT | |
87 | (((ulg)(extent)eb_ucsize) != eb_ucsize) || | 110 | (((ulg)(extent)eb_ucsize) != eb_ucsize) || | |
111 | @@ -2701,6 +2731,12 @@ __GDEF | |||
112 | int repeated_buf_err; | |||
113 | bz_stream bstrm; | |||
114 | ||||
115 | + if (G.incnt <= 0 && G.csize <= 0L) { | |||
116 | + /* avoid an infinite loop */ | |||
117 | + Trace((stderr, "UZbunzip2() got empty input\n")); | |||
118 | + return 2; | |||
119 | + } | |||
120 | + | |||
121 | #if (defined(DLL) && !defined(NO_SLIDE_REDIR)) | |||
122 | if (G.redirect_slide) | |||
123 | wsize = G.redirect_size, redirSlide = G.redirect_buffer; |