Module Name: src Committed By: riz Date: Fri Aug 19 22:30:35 UTC 2011
Modified Files: src/usr.bin/compress [netbsd-4-0]: zopen.c src/usr.bin/gzip [netbsd-4-0]: zuncompress.c Log Message: Pull up following revision(s) (requested by joerg in ticket #1433): usr.bin/compress/zopen.c: revision 1.14-1.15 xfree/xc/lib/font/fontfile/decompress.c: revision 1.2 xfree/xc/extras/freetype2/src/lzw/zopen.c: revision 1.2 usr.bin/gzip/zuncompress.c: revision 1.9-1.11 Fix CVS-2011-2895, buffer overflow in decompress provisional fix for CVS-2011-2895, buffer overflow when uncompressing provisional fix for CVE-2011-2895, buffer overflow in decompression set errno on overflow return. Do proper input validation without penalizing performance. Do proper input validation. Allow decompressing all input streams. Increase robustness of LZW decoding to avoid buffer overflow on arbitrary manipulated input streams in combination with uninitalised memory. Increase strictness of LZW parser. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.8.22.1 src/usr.bin/compress/zopen.c cvs rdiff -u -r1.6 -r1.6.16.1 src/usr.bin/gzip/zuncompress.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/compress/zopen.c diff -u src/usr.bin/compress/zopen.c:1.8 src/usr.bin/compress/zopen.c:1.8.22.1 --- src/usr.bin/compress/zopen.c:1.8 Thu Aug 7 11:13:29 2003 +++ src/usr.bin/compress/zopen.c Fri Aug 19 22:30:34 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $ */ +/* $NetBSD: zopen.c,v 1.8.22.1 2011/08/19 22:30:34 riz Exp $ */ /*- * Copyright (c) 1985, 1986, 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; #else -static char rcsid[] = "$NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $"; +static char rcsid[] = "$NetBSD: zopen.c,v 1.8.22.1 2011/08/19 22:30:34 riz Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -488,7 +488,7 @@ block_compress = maxbits & BLOCK_MASK; maxbits &= BIT_MASK; maxmaxcode = 1L << maxbits; - if (maxbits > BITS) { + if (maxbits > BITS || maxbits < 12) { errno = EFTYPE; return (-1); } @@ -499,14 +499,7 @@ tab_suffixof(code) = (char_type) code; } free_ent = block_compress ? FIRST : 256; - - finchar = oldcode = getcode(zs); - if (oldcode == -1) /* EOF already? */ - return (0); /* Get out of here */ - - /* First code must be 8 bits = char. */ - *bp++ = (u_char)finchar; - count--; + oldcode = -1; stackp = de_stack; while ((code = getcode(zs)) > -1) { @@ -515,17 +508,28 @@ for (code = 255; code >= 0; code--) tab_prefixof(code) = 0; clear_flg = 1; - free_ent = FIRST - 1; - if ((code = getcode(zs)) == -1) /* O, untimely death! */ - break; + free_ent = FIRST; + oldcode = -1; + continue; } incode = code; - /* Special case for KwKwK string. */ + /* Special case for kWkWk string. */ if (code >= free_ent) { + if (code > free_ent || oldcode == -1) { + /* Bad stream. */ + errno = EINVAL; + return (-1); + } *stackp++ = finchar; code = oldcode; } + /* + * The above condition ensures that code < free_ent. + * The construction of tab_prefixof in turn guarantees that + * each iteration decreases code and therefore stack usage is + * bound by 1 << BITS - 256. + */ /* Generate output characters in reverse order. */ while (code >= 256) { @@ -542,7 +546,7 @@ } while (stackp > de_stack); /* Generate the new entry. */ - if ((code = free_ent) < maxmaxcode) { + if ((code = free_ent) < maxmaxcode && oldcode != -1) { tab_prefixof(code) = (u_short) oldcode; tab_suffixof(code) = finchar; free_ent = code + 1; Index: src/usr.bin/gzip/zuncompress.c diff -u src/usr.bin/gzip/zuncompress.c:1.6 src/usr.bin/gzip/zuncompress.c:1.6.16.1 --- src/usr.bin/gzip/zuncompress.c:1.6 Tue Nov 22 09:05:30 2005 +++ src/usr.bin/gzip/zuncompress.c Fri Aug 19 22:30:34 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: zuncompress.c,v 1.6 2005/11/22 09:05:30 mrg Exp $ */ +/* $NetBSD: zuncompress.c,v 1.6.16.1 2011/08/19 22:30:34 riz Exp $ */ /*- * Copyright (c) 1985, 1986, 1992, 1993 @@ -246,7 +246,7 @@ zs->zs_block_compress = zs->zs_maxbits & BLOCK_MASK; zs->zs_maxbits &= BIT_MASK; zs->zs_maxmaxcode = 1L << zs->zs_maxbits; - if (zs->zs_maxbits > BITS) { + if (zs->zs_maxbits > BITS || zs->zs_maxbits < 12) { errno = EFTYPE; return (-1); } @@ -258,13 +258,7 @@ } zs->zs_free_ent = zs->zs_block_compress ? FIRST : 256; - zs->u.r.zs_finchar = zs->u.r.zs_oldcode = getcode(zs); - if (zs->u.r.zs_oldcode == -1) /* EOF already? */ - return (0); /* Get out of here */ - - /* First code must be 8 bits = char. */ - *bp++ = (u_char)zs->u.r.zs_finchar; - count--; + zs->u.r.zs_oldcode = -1; zs->u.r.zs_stackp = de_stack; while ((zs->u.r.zs_code = getcode(zs)) > -1) { @@ -274,17 +268,29 @@ zs->u.r.zs_code--) tab_prefixof(zs->u.r.zs_code) = 0; zs->zs_clear_flg = 1; - zs->zs_free_ent = FIRST - 1; - if ((zs->u.r.zs_code = getcode(zs)) == -1) /* O, untimely death! */ - break; + zs->zs_free_ent = FIRST; + zs->u.r.zs_oldcode = -1; + continue; } zs->u.r.zs_incode = zs->u.r.zs_code; /* Special case for KwKwK string. */ if (zs->u.r.zs_code >= zs->zs_free_ent) { + if (zs->u.r.zs_code > zs->zs_free_ent || + zs->u.r.zs_oldcode == -1) { + /* Bad stream. */ + errno = EINVAL; + return (-1); + } *zs->u.r.zs_stackp++ = zs->u.r.zs_finchar; zs->u.r.zs_code = zs->u.r.zs_oldcode; } + /* + * The above condition ensures that code < free_ent. + * The construction of tab_prefixof in turn guarantees that + * each iteration decreases code and therefore stack usage is + * bound by 1 << BITS - 256. + */ /* Generate output characters in reverse order. */ while (zs->u.r.zs_code >= 256) { @@ -301,7 +307,8 @@ } while (zs->u.r.zs_stackp > de_stack); /* Generate the new entry. */ - if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode) { + if ((zs->u.r.zs_code = zs->zs_free_ent) < zs->zs_maxmaxcode && + zs->u.r.zs_oldcode != -1) { tab_prefixof(zs->u.r.zs_code) = (u_short) zs->u.r.zs_oldcode; tab_suffixof(zs->u.r.zs_code) = zs->u.r.zs_finchar; zs->zs_free_ent = zs->u.r.zs_code + 1;