Subject: Info-ZIP UnZip buffer overflow
From: mancha <mancha1 AT zoho DOT com>
Date: Wed, 11 Feb 2015

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.

--- a/extract.c
+++ b/extract.c
@@ -2228,6 +2228,7 @@
     ulg eb_ucsize;
     uch *eb_ucptr;
     int r;
+    ush eb_compr_method;
 
     if (compr_offset < 4)                /* field is not compressed: */
         return PK_OK;                    /* do nothing and signal OK */
@@ -2244,6 +2245,15 @@
      ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
         return IZ_EF_TRUNC;             /* no/bad compressed data! */
 
+    /* 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_CMPRHEADLEN + eb_ucsize))
+        return PK_ERR;
+
     if (
 #ifdef INT_16BIT
         (((ulg)(extent)eb_ucsize) != eb_ucsize) ||