unzip: patch CVE-2015-7696, CVE-2015-7697 and integer underflow
authorÁlvaro Fernández Rojas <noltari@gmail.com>
Sun, 1 Nov 2015 15:19:56 +0000 (16:19 +0100)
committerÁlvaro Fernández Rojas <noltari@gmail.com>
Sun, 1 Nov 2015 15:19:56 +0000 (16:19 +0100)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
utils/unzip/Makefile
utils/unzip/patches/005-CVE-2015-7696-heap-overflow.patch [new file with mode: 0644]
utils/unzip/patches/006-CVE-2015-7697-infinite-loop.patch [new file with mode: 0644]
utils/unzip/patches/007-integer-underflow-csiz_decrypted.patch [new file with mode: 0644]

index cdd6d2ae91f7c2f9f301ed5641d19bc072afa420..112b3f4e85ba2e1fd89be8563821ce32538d3d77 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=unzip
 PKG_REV:=60
 PKG_VERSION:=6.0
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)$(PKG_REV).tar.gz
 PKG_SOURCE_URL:=@SF/infozip
diff --git a/utils/unzip/patches/005-CVE-2015-7696-heap-overflow.patch b/utils/unzip/patches/005-CVE-2015-7696-heap-overflow.patch
new file mode 100644 (file)
index 0000000..df758a1
--- /dev/null
@@ -0,0 +1,21 @@
+--- a/crypt.c
++++ b/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]));
+     }
diff --git a/utils/unzip/patches/006-CVE-2015-7697-infinite-loop.patch b/utils/unzip/patches/006-CVE-2015-7697-infinite-loop.patch
new file mode 100644 (file)
index 0000000..a8376b2
--- /dev/null
@@ -0,0 +1,15 @@
+--- a/extract.c
++++ b/extract.c
+@@ -2728,6 +2728,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;
diff --git a/utils/unzip/patches/007-integer-underflow-csiz_decrypted.patch b/utils/unzip/patches/007-integer-underflow-csiz_decrypted.patch
new file mode 100644 (file)
index 0000000..738ea52
--- /dev/null
@@ -0,0 +1,21 @@
+--- a/extract.c
++++ b/extract.c
+@@ -1257,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),