Hi, There are a bunch of CVE and other fixes for unzip in debian and redhat bug tracker. I added the links to the patch files. The fix for CVE-2014-9636 got an update, so we have a diff onto of a diff.
Unfortunately unzip did its last release in 2009 and they do not offer patches on their web site. ok? bluhm Index: archivers/unzip/Makefile =================================================================== RCS file: /data/mirror/openbsd/cvs/ports/archivers/unzip/Makefile,v retrieving revision 1.59 diff -u -p -r1.59 Makefile --- archivers/unzip/Makefile 13 Sep 2016 11:44:06 -0000 1.59 +++ archivers/unzip/Makefile 21 Mar 2017 15:24:39 -0000 @@ -7,7 +7,7 @@ COMMENT = extract, list & test files in VERSION = 6.0 DISTNAME = unzip${VERSION:S/.//} PKGNAME = unzip-${VERSION} -REVISION = 9 +REVISION = 10 CATEGORIES = archivers MASTER_SITES = ${MASTER_SITE_SOURCEFORGE:=infozip/} \ ftp://ftp.info-zip.org/pub/infozip/src/ Index: archivers/unzip/patches/patch-crypt_c =================================================================== RCS file: archivers/unzip/patches/patch-crypt_c diff -N archivers/unzip/patches/patch-crypt_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ archivers/unzip/patches/patch-crypt_c 21 Mar 2017 16:24:58 -0000 @@ -0,0 +1,28 @@ +$OpenBSD$ + +Fix CVE-2015-7696: upstream fix for heap overflow + https://bugs.debian.org/802162 + https://bugzilla.redhat.com/show_bug.cgi?id=1260944 + https://bugzilla.redhat.com/attachment.cgi?id=1073002 + +--- crypt.c.orig Fri Jan 5 16:47:36 2007 ++++ crypt.c Tue Mar 21 16:10:27 2017 +@@ -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])); + } Index: archivers/unzip/patches/patch-extract_c =================================================================== RCS file: /data/mirror/openbsd/cvs/ports/archivers/unzip/patches/patch-extract_c,v retrieving revision 1.1 diff -u -p -r1.1 patch-extract_c --- archivers/unzip/patches/patch-extract_c 6 Feb 2015 21:37:04 -0000 1.1 +++ archivers/unzip/patches/patch-extract_c 21 Mar 2017 16:24:58 -0000 @@ -1,11 +1,20 @@ $OpenBSD: patch-extract_c,v 1.1 2015/02/06 21:37:04 naddy Exp $ +Fix CVE-2015-7696: prevent unsigned overflow on invalid input + https://bugzilla.redhat.com/attachment.cgi?id=1075942 + https://bugzilla.redhat.com/show_bug.cgi?id=1260944 Fix CVE-2014-8139: CRC32 verification heap-based overflow + https://bugzilla.redhat.com/show_bug.cgi?id=1174844 + https://bugzilla.redhat.com/attachment.cgi?id=989833 Fix CVE-2014-8140: out-of-bounds write issue in test_compr_eb() Fix CVE-2014-9636: out-of-bounds read/write in test_compr_eb() +Fix CVE-2015-7697: infinite loop when extracting empty bzip2 data + https://bugs.debian.org/802160 + https://bugzilla.redhat.com/show_bug.cgi?id=1260944 + https://bugzilla.redhat.com/attachment.cgi?id=1073339 --- extract.c.orig Sat Mar 14 02:32:52 2009 -+++ extract.c Thu Feb 5 18:58:23 2015 ++++ extract.c Tue Mar 21 16:10:27 2017 @@ -1,5 +1,5 @@ /* - Copyright (c) 1990-2009 Info-ZIP. All rights reserved. @@ -22,7 +31,26 @@ Fix CVE-2014-9636: out-of-bounds read/wr static ZCONST char Far InvalidComprDataEAs[] = " invalid compressed data for EAs\n"; # if (defined(WIN32) && defined(NTSD_EAS)) -@@ -2023,7 +2025,8 @@ static int TestExtraField(__G__ ef, ef_len) +@@ -1255,8 +1257,17 @@ static int extract_or_test_entrylist(__G__ numchunk, + if (G.lrec.compression_method == STORED) { + zusz_t csiz_decrypted = G.lrec.csize; + +- if (G.pInfo->encrypted) ++ if (G.pInfo->encrypted) { ++ if (csiz_decrypted < 12) { ++ /* handle the error now to prevent unsigned overflow */ ++ Info(slide, 0x401, ((char *)slide, ++ LoadFarStringSmall(ErrUnzipNoFile), ++ LoadFarString(InvalidComprData), ++ LoadFarStringSmall2(Inflate))); ++ return PK_ERR; ++ } + csiz_decrypted -= 12; ++ } + if (G.lrec.ucsize != csiz_decrypted) { + Info(slide, 0x401, ((char *)slide, + LoadFarStringSmall2(WrnStorUCSizCSizDiff), +@@ -2023,7 +2034,8 @@ static int TestExtraField(__G__ ef, ef_len) ebID = makeword(ef); ebLen = (unsigned)makeword(ef+EB_LEN); @@ -32,7 +60,7 @@ Fix CVE-2014-9636: out-of-bounds read/wr /* Discovered some extra field inconsistency! */ if (uO.qflag) Info(slide, 1, ((char *)slide, "%-22s ", -@@ -2158,11 +2161,19 @@ static int TestExtraField(__G__ ef, ef_len) +@@ -2158,11 +2170,19 @@ static int TestExtraField(__G__ ef, ef_len) } break; case EF_PKVMS: @@ -53,7 +81,7 @@ Fix CVE-2014-9636: out-of-bounds read/wr break; case EF_PKW32: case EF_PKUNIX: -@@ -2217,14 +2228,30 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offs +@@ -2217,15 +2237,32 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offs ulg eb_ucsize; uch *eb_ucptr; int r; @@ -76,14 +104,29 @@ Fix CVE-2014-9636: out-of-bounds read/wr + ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) || + ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN)))) + return IZ_EF_TRUNC; /* no/bad compressed data! */ -+ -+ /* 2014-11-03 Michal Zalewski, SMS. + ++ /* 2015-02-10 Mancha(?), Michal Zalewski, Tomas Hoger, SMS. + * For STORE method, compressed and uncompressed sizes must agree. + * http://www.info-zip.org/phpBB3/viewtopic.php?f=7&t=450 + */ + eb_compr_method = makeword( eb + (EB_HEADSIZE + compr_offset)); -+ if ((eb_compr_method == STORED) && (eb_size - compr_offset != eb_ucsize)) ++ if ((eb_compr_method == STORED) && ++ (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize)) + return PK_ERR; - ++ if ( #ifdef INT_16BIT + (((ulg)(extent)eb_ucsize) != eb_ucsize) || +@@ -2700,6 +2737,12 @@ __GDEF + int err=BZ_OK; + int repeated_buf_err; + bz_stream bstrm; ++ ++ if (G.incnt <= 0 && G.csize <= 0L) { ++ /* avoid an infinite loop */ ++ Trace((stderr, "UZbunzip2() got empty input\n")); ++ return 2; ++ } + + #if (defined(DLL) && !defined(NO_SLIDE_REDIR)) + if (G.redirect_slide) Index: archivers/unzip/patches/patch-list_c =================================================================== RCS file: archivers/unzip/patches/patch-list_c diff -N archivers/unzip/patches/patch-list_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ archivers/unzip/patches/patch-list_c 21 Mar 2017 16:24:58 -0000 @@ -0,0 +1,40 @@ +$OpenBSD$ + +Fix: increase size of cfactorstr array to avoid buffer overflow + https://bugs.debian.org/741384 +Fix CVE-2014-9913: buffer overflow in unzip + https://sourceforge.net/p/infozip/bugs/27/ + https://bugs.debian.org/847485 + https://launchpad.net/bugs/387350 + +--- list.c.orig Sun Feb 8 18:11:34 2009 ++++ list.c Tue Mar 21 16:10:27 2017 +@@ -97,7 +97,7 @@ int list_files(__G) /* return PK-type error code */ + { + int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL; + #ifndef WINDLL +- char sgn, cfactorstr[10]; ++ char sgn, cfactorstr[12]; + int longhdr=(uO.vflag>1); + #endif + int date_format; +@@ -339,7 +339,18 @@ int list_files(__G) /* return PK-type error code */ + G.crec.compression_method == ENHDEFLATED) { + methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3]; + } else if (methnum >= NUM_METHODS) { +- sprintf(&methbuf[4], "%03u", G.crec.compression_method); ++ /* 2013-02-26 SMS. ++ * http://sourceforge.net/p/infozip/bugs/27/ CVE-2014-9913. ++ * Unexpectedly large compression methods overflow ++ * &methbuf[]. Use the old, three-digit decimal format ++ * for values which fit. Otherwise, sacrifice the ++ * colon, and use four-digit hexadecimal. ++ */ ++ if (G.crec.compression_method <= 999) { ++ sprintf( &methbuf[ 4], "%03u", G.crec.compression_method); ++ } else { ++ sprintf( &methbuf[ 3], "%04X", G.crec.compression_method); ++ } + } + + #if 0 /* GRR/Euro: add this? */ Index: archivers/unzip/patches/patch-process_c =================================================================== RCS file: /data/mirror/openbsd/cvs/ports/archivers/unzip/patches/patch-process_c,v retrieving revision 1.2 diff -u -p -r1.2 patch-process_c --- archivers/unzip/patches/patch-process_c 6 Feb 2015 21:37:04 -0000 1.2 +++ archivers/unzip/patches/patch-process_c 21 Mar 2017 16:24:58 -0000 @@ -1,10 +1,16 @@ $OpenBSD: patch-process_c,v 1.2 2015/02/06 21:37:04 naddy Exp $ -Fix extraction of symlinks +Fix: handle the PKWare verification bit of internal attributes + https://bugs.debian.org/630078 +Fix: extraction of symlinks Fix CVE-2014-8141: out-of-bounds read issues in getZip64Data() +Fix: do not ignore extra fields containing Unix Timestamps + https://bugs.debian.org/842993 +Fix: restore uid and gid information when requested + https://bugs.debian.org/689212 --- process.c.orig Fri Mar 6 02:25:10 2009 -+++ process.c Thu Feb 5 18:57:59 2015 ++++ process.c Tue Mar 21 16:10:27 2017 @@ -1,5 +1,5 @@ /* - Copyright (c) 1990-2009 Info-ZIP. All rights reserved. @@ -12,7 +18,21 @@ Fix CVE-2014-8141: out-of-bounds read is See the accompanying file LICENSE, version 2009-Jan-02 or later (the contents of which are also included in unzip.h) for terms of use. -@@ -1751,6 +1751,12 @@ int process_cdir_file_hdr(__G) /* return PK-type er +@@ -1729,6 +1729,13 @@ int process_cdir_file_hdr(__G) /* return PK-type er + else if (uO.L_flag > 1) /* let -LL force lower case for all names */ + G.pInfo->lcflag = 1; + ++ /* Handle the PKWare verification bit, bit 2 (0x0004) of internal ++ attributes. If this is set, then a verification checksum is in the ++ first 3 bytes of the external attributes. In this case all we can use ++ for setting file attributes is the last external attributes byte. */ ++ if (G.crec.internal_file_attributes & 0x0004) ++ G.crec.external_file_attributes &= (ulg)0xff; ++ + /* do Amigas (AMIGA_) also have volume labels? */ + if (IS_VOLID(G.crec.external_file_attributes) && + (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ || +@@ -1751,6 +1758,12 @@ int process_cdir_file_hdr(__G) /* return PK-type er = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11); #endif @@ -25,7 +45,7 @@ Fix CVE-2014-8141: out-of-bounds read is return PK_COOL; } /* end function process_cdir_file_hdr() */ -@@ -1888,48 +1894,82 @@ int getZip64Data(__G__ ef_buf, ef_len) +@@ -1888,48 +1901,82 @@ int getZip64Data(__G__ ef_buf, ef_len) and a 4-byte version of disk start number. Sets both local header and central header fields. Not terribly clever, but it means that this procedure is only called in one place. @@ -124,3 +144,53 @@ Fix CVE-2014-8141: out-of-bounds read is ef_buf += (eb_len + EB_HEADSIZE); ef_len -= (eb_len + EB_HEADSIZE); } +@@ -2867,10 +2914,13 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos + break; + + case EF_IZUNIX2: +- if (have_new_type_eb == 0) { +- flags &= ~0x0ff; /* ignore any previous IZUNIX field */ ++ if (have_new_type_eb == 0) { /* (< 1) */ + have_new_type_eb = 1; + } ++ if (have_new_type_eb <= 1) { ++ /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */ ++ flags &= 0x0ff; ++ } + #ifdef IZ_HAVE_UXUIDGID + if (have_new_type_eb > 1) + break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */ +@@ -2886,6 +2936,8 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos + /* new 3rd generation Unix ef */ + have_new_type_eb = 2; + ++ /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */ ++ flags &= 0x0ff; + /* + Version 1 byte version of this extra field, currently 1 + UIDSize 1 byte Size of UID field +@@ -2897,7 +2949,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos + #ifdef IZ_HAVE_UXUIDGID + if (eb_len >= EB_UX3_MINLEN + && z_uidgid != NULL +- && (*((EB_HEADSIZE + 0) + ef_buf) == 1) ++ && (*((EB_HEADSIZE + 0) + ef_buf) == 1)) + /* only know about version 1 */ + { + uch uid_size; +@@ -2906,13 +2958,11 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos + uid_size = *((EB_HEADSIZE + 1) + ef_buf); + gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf); + +- flags &= ~0x0ff; /* ignore any previous UNIX field */ +- + if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf, +- uid_size, z_uidgid[0]) ++ uid_size, &z_uidgid[0]) + && + read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf, +- gid_size, z_uidgid[1]) ) ++ gid_size, &z_uidgid[1]) ) + { + flags |= EB_UX2_VALID; /* signal success */ + } Index: archivers/unzip/patches/patch-zipinfo_c =================================================================== RCS file: archivers/unzip/patches/patch-zipinfo_c diff -N archivers/unzip/patches/patch-zipinfo_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ archivers/unzip/patches/patch-zipinfo_c 21 Mar 2017 16:24:58 -0000 @@ -0,0 +1,38 @@ +$OpenBSD$ + +Fix CVE-2016-9844: buffer overflow in zipinfo + https://bugs.debian.org/847486 + https://launchpad.net/bugs/1643750 +Do not crash when hostver byte is >= 100 + +--- zipinfo.c.orig Sun Feb 8 18:04:30 2009 ++++ zipinfo.c Tue Mar 21 16:10:27 2017 +@@ -1921,7 +1921,18 @@ static int zi_short(__G) /* return PK-type error cod + ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3); + methbuf[3] = dtype[dnum]; + } else if (methnum >= NUM_METHODS) { /* unknown */ +- sprintf(&methbuf[1], "%03u", G.crec.compression_method); ++ /* 2016-12-05 SMS. ++ * https://launchpad.net/bugs/1643750 ++ * Unexpectedly large compression methods overflow ++ * &methbuf[]. Use the old, three-digit decimal format ++ * for values which fit. Otherwise, sacrifice the "u", ++ * and use four-digit hexadecimal. ++ */ ++ if (G.crec.compression_method <= 999) { ++ sprintf( &methbuf[ 1], "%03u", G.crec.compression_method); ++ } else { ++ sprintf( &methbuf[ 0], "%04X", G.crec.compression_method); ++ } + } + + for (k = 0; k < 15; ++k) +@@ -2114,7 +2125,7 @@ static int zi_short(__G) /* return PK-type error cod + else + attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */ + +- sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10); ++ sprintf(&attribs[11], "%2u.%u", hostver/10, hostver%10); + break; + + } /* end switch (hostnum: external attributes format) */