unzip: Patch for CVE-2014-81{39,40,41}.

+214 -1
+47
pkgs/tools/archivers/unzip/CVE-2014-8139.diff
··· 1 + From RedHat: https://bugzilla.redhat.com/attachment.cgi?id=971984&action=diff&context=patch&collapsed=&headers=1&format=raw 2 + 3 + --- unzip60/extract.c 2010-04-03 14:41:55 -0500 4 + +++ unzip60/extract.c 2014-12-03 15:33:35 -0600 5 + @@ -1,5 +1,5 @@ 6 + /* 7 + - Copyright (c) 1990-2009 Info-ZIP. All rights reserved. 8 + + Copyright (c) 1990-2014 Info-ZIP. All rights reserved. 9 + 10 + See the accompanying file LICENSE, version 2009-Jan-02 or later 11 + (the contents of which are also included in unzip.h) for terms of use. 12 + @@ -298,6 +298,8 @@ 13 + #ifndef SFX 14 + static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \ 15 + EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n"; 16 + + static ZCONST char Far TooSmallEFlength[] = "bad extra-field entry:\n \ 17 + + EF block length (%u bytes) invalid (< %d)\n"; 18 + static ZCONST char Far InvalidComprDataEAs[] = 19 + " invalid compressed data for EAs\n"; 20 + # if (defined(WIN32) && defined(NTSD_EAS)) 21 + @@ -2023,7 +2025,8 @@ 22 + ebID = makeword(ef); 23 + ebLen = (unsigned)makeword(ef+EB_LEN); 24 + 25 + - if (ebLen > (ef_len - EB_HEADSIZE)) { 26 + + if (ebLen > (ef_len - EB_HEADSIZE)) 27 + + { 28 + /* Discovered some extra field inconsistency! */ 29 + if (uO.qflag) 30 + Info(slide, 1, ((char *)slide, "%-22s ", 31 + @@ -2032,6 +2035,16 @@ 32 + ebLen, (ef_len - EB_HEADSIZE))); 33 + return PK_ERR; 34 + } 35 + + else if (ebLen < EB_HEADSIZE) 36 + + { 37 + + /* Extra block length smaller than header length. */ 38 + + if (uO.qflag) 39 + + Info(slide, 1, ((char *)slide, "%-22s ", 40 + + FnFilter1(G.filename))); 41 + + Info(slide, 1, ((char *)slide, LoadFarString(TooSmallEFlength), 42 + + ebLen, EB_HEADSIZE)); 43 + + return PK_ERR; 44 + + } 45 + 46 + switch (ebID) { 47 + case EF_OS2:
+26
pkgs/tools/archivers/unzip/CVE-2014-8140.diff
··· 1 + From RedHat: https://bugzilla.redhat.com/attachment.cgi?id=969621&action=diff 2 + (unzip60/ path prefix added) 3 + 4 + --- unzip60/extract.c 2009-03-14 02:32:52.000000000 +0100 5 + +++ unzip60/extract.c 2014-12-05 22:43:13.000000000 +0100 6 + @@ -2221,10 +2234,17 @@ static int test_compr_eb(__G__ eb, eb_si 7 + if (compr_offset < 4) /* field is not compressed: */ 8 + return PK_OK; /* do nothing and signal OK */ 9 + 10 + + /* Return no/bad-data error status if any problem is found: 11 + + * 1. eb_size is too small to hold the uncompressed size 12 + + * (eb_ucsize). (Else extract eb_ucsize.) 13 + + * 2. eb_ucsize is zero (invalid). 2014-12-04 SMS. 14 + + * 3. eb_ucsize is positive, but eb_size is too small to hold 15 + + * the compressed data header. 16 + + */ 17 + if ((eb_size < (EB_UCSIZE_P + 4)) || 18 + - ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L && 19 + - eb_size <= (compr_offset + EB_CMPRHEADLEN))) 20 + - return IZ_EF_TRUNC; /* no compressed data! */ 21 + + ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) || 22 + + ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN)))) 23 + + return IZ_EF_TRUNC; /* no/bad compressed data! */ 24 + 25 + if ( 26 + #ifdef INT_16BIT
+136
pkgs/tools/archivers/unzip/CVE-2014-8141.diff
··· 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) {
+5 -1
pkgs/tools/archivers/unzip/default.nix
··· 9 9 sha256 = "0dxx11knh3nk95p2gg2ak777dd11pr7jx5das2g49l262scrcv83"; 10 10 }; 11 11 12 - patches = stdenv.lib.optional enableNLS 12 + patches = [ 13 + ./CVE-2014-8139.diff 14 + ./CVE-2014-8140.diff 15 + ./CVE-2014-8141.diff 16 + ] ++ stdenv.lib.optional enableNLS 13 17 (fetchurl { 14 18 url = "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/app-arch/unzip/files/unzip-6.0-natspec.patch?revision=1.1"; 15 19 name = "unzip-6.0-natspec.patch";