Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 3 Nov 2014 07:42:06 +0000
From: mancha <mancha1@...o.com>
To: oss-security@...ts.openwall.com
Cc: Zip-Bugs@...ts.wku.edu, Christian.Spieler@...nline.de
Subject: Re: unzip -t crasher

On Sun, Nov 02, 2014 at 07:06:40PM +0100, Jakub Wilk wrote:
> Latest American fuzzy lop[0] tarball[1] contains a zip file that
> crashes unzip -t:
> 
> $ unzip -qt afl-0.43b/docs/samples/unzip_t_malloc.zip foo/:
> mismatching "local" filename (™/UT), continuing with "central"
> filename version *** Error in `unzip': free(): corrupted unsorted
> chunks: 0x00000000015d0170 ***
> 
> I'm not sure if inclusion of said zip file was intentional, but since
> the cat is already out of the bag, I thought I'll let you know.

Cats shouldn't be in bags, anyways.

The crasher has an OS/2 extra field that claims to have a compressed
block size of 52735 bytes and an uncompressed block size of 127 bytes.

The attached patch against UnZip 6.0 ensures, within extra fields, 
size(compressed) <= size(uncompressed) and should fix this issue.

--mancha

PS If the attachment gets mangled, it's also at:
http://sf.net/projects/mancha/files/sec/unzip-6.0_overflow.diff


From 0f4bd53ef007b2b593a68bb374f4babf644f4287 Mon Sep 17 00:00:00 2001
From: mancha <mancha1 AT zoho DOT com>
Date: Mon, 3 Nov 2014
Subject: Info-ZIP UnZip buffer overflow

By carefully crafting a corrupt ZIP archive with extra fields that
purport to have compressed blocks larger than the corresponding
uncompressed blocks, an attacker can trigger a heap overflow which can
result in application crash or possibly have unspecified other impact.

This patch ensures extra fields can't claim to contain a block with a 
a compressed size larger than its uncompressed size.

---
 extract.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/extract.c
+++ b/extract.c
@@ -2226,6 +2226,9 @@ static int test_compr_eb(__G__ eb, eb_si
          eb_size <= (compr_offset + EB_CMPRHEADLEN)))
         return IZ_EF_TRUNC;               /* no compressed data! */
 
+    if (eb_size - compr_offset > (unsigned)eb_ucsize)
+	return IZ_EF_TRUNC;		  /* compressed > uncompressed */
+
     if (
 #ifdef INT_16BIT
         (((ulg)(extent)eb_ucsize) != eb_ucsize) ||


[ CONTENT OF TYPE application/pgp-signature SKIPPED ]

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ