unzip: fix CVE-2015-7696, CVE-2015-7697, and an integer underflow.

patches from Debian via pkgsrc. Close #2946
This commit is contained in:
Juan RP 2015-11-12 08:46:57 +01:00
parent 1f9f3450c4
commit 8868443efb
3 changed files with 86 additions and 23 deletions

View File

@ -0,0 +1,26 @@
$NetBSD: patch-crypt.c,v 1.1 2015/11/11 12:47:27 wiz 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]));
}

View File

@ -1,11 +1,26 @@
$NetBSD: patch-extract.c,v 1.1 2014/12/25 16:48:33 wiz Exp $
$NetBSD: patch-extract.c,v 1.3 2015/11/11 12:47:27 wiz Exp $
Fixes for
* https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-8139
* https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-8140
* http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow2.diff via
http://seclists.org/oss-sec/2014/q4/1131 and
http://seclists.org/oss-sec/2014/q4/507
http://seclists.org/oss-sec/2014/q4/507 and later version
http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow3.diff via
http://www.openwall.com/lists/oss-security/2015/02/11/7
By carefully crafting a corrupt ZIP archive with "extra fields" that
purport to have compressed blocks larger than the corresponding
uncompressed blocks in STORED no-compression mode, an attacker can
trigger a heap overflow that can result in application crash or
possibly have other unspecified impact.
This patch ensures that when extra fields use STORED mode, the
"compressed" and uncompressed block sizes match.
* CVE-2015-7697 (from Debian)
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802160
* integer underflow
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802160
--- extract.c.orig 2009-03-14 01:32:52.000000000 +0000
+++ extract.c
@ -25,7 +40,26 @@ Fixes for
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_l
@@ -1255,8 +1257,17 @@ static int extract_or_test_entrylist(__G
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_l
ebID = makeword(ef);
ebLen = (unsigned)makeword(ef+EB_LEN);
@ -35,7 +69,7 @@ Fixes for
/* Discovered some extra field inconsistency! */
if (uO.qflag)
Info(slide, 1, ((char *)slide, "%-22s ",
@@ -2032,6 +2035,16 @@ static int TestExtraField(__G__ ef, ef_l
@@ -2032,6 +2044,16 @@ static int TestExtraField(__G__ ef, ef_l
ebLen, (ef_len - EB_HEADSIZE)));
return PK_ERR;
}
@ -52,7 +86,7 @@ Fixes for
switch (ebID) {
case EF_OS2:
@@ -2217,14 +2230,28 @@ static int test_compr_eb(__G__ eb, eb_si
@@ -2217,6 +2239,7 @@ static int test_compr_eb(__G__ eb, eb_si
ulg eb_ucsize;
uch *eb_ucptr;
int r;
@ -60,27 +94,30 @@ Fixes for
if (compr_offset < 4) /* field is not compressed: */
return PK_OK; /* do nothing and signal OK */
@@ -2226,6 +2249,13 @@ static int test_compr_eb(__G__ eb, eb_si
eb_size <= (compr_offset + EB_CMPRHEADLEN)))
return IZ_EF_TRUNC; /* no compressed data! */
+ /* Return no/bad-data error status if any problem is found:
+ * 1. eb_size is too small to hold the uncompressed size
+ * (eb_ucsize). (Else extract eb_ucsize.)
+ * 2. eb_ucsize is zero (invalid). 2014-12-04 SMS.
+ * 3. eb_ucsize is positive, but eb_size is too small to hold
+ * the compressed data header.
+ */
if ((eb_size < (EB_UCSIZE_P + 4)) ||
- ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
- eb_size <= (compr_offset + EB_CMPRHEADLEN)))
- return IZ_EF_TRUNC; /* no compressed data! */
+ ((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! */
+
+ method = makeword(eb + (EB_HEADSIZE + compr_offset));
+ if ((method == STORED) && (eb_size - compr_offset != eb_ucsize))
+ if ((method == STORED) &&
+ (eb_size - compr_offset - EB_CMPRHEADLEN != eb_ucsize))
+ return PK_ERR; /* compressed & uncompressed
+ * should match in STORED
+ * method */
+
if (
#ifdef INT_16BIT
(((ulg)(extent)eb_ucsize) != eb_ucsize) ||
@@ -2701,6 +2731,12 @@ __GDEF
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)
wsize = G.redirect_size, redirSlide = G.redirect_buffer;

View File

@ -1,7 +1,7 @@
# Template file for 'unzip'
pkgname=unzip
version=6.0
revision=7
revision=8
makedepends="bzip2-devel"
wrksrc=unzip60
short_desc="List, test and extract compressed files in a ZIP archive"