Module Name:    xsrc
Committed By:   riz
Date:           Fri Aug 19 22:30:28 UTC 2011

Modified Files:
        xsrc/xfree/xc/extras/freetype2/src/lzw [netbsd-4-0]: zopen.c
        xsrc/xfree/xc/lib/font/fontfile [netbsd-4-0]: decompress.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.1.1.1 -r1.1.1.1.8.1 \
    xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.20.1 \
    xsrc/xfree/xc/lib/font/fontfile/decompress.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c
diff -u xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c:1.1.1.1 xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c:1.1.1.1.8.1
--- xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c:1.1.1.1	Fri Mar 18 13:07:34 2005
+++ xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c	Fri Aug 19 22:30:27 2011
@@ -1,5 +1,5 @@
 /* $XFree86: xc/extras/freetype2/src/lzw/zopen.c,v 1.2 2004/12/16 22:15:48 tsi Exp $ */
-/*	$NetBSD: zopen.c,v 1.1.1.1 2005/03/18 13:07:34 tron Exp $	*/
+/*	$NetBSD: zopen.c,v 1.1.1.1.8.1 2011/08/19 22:30:27 riz Exp $	*/
 
 /*-
  * Copyright (c) 1985, 1986, 1992, 1993
@@ -47,7 +47,7 @@
 #if 0
 static char sccsid[] = "@(#)zopen.c	8.1 (Berkeley) 6/27/93";
 #else
-static char rcsid[] = "$NetBSD: zopen.c,v 1.1.1.1 2005/03/18 13:07:34 tron Exp $";
+static char rcsid[] = "$NetBSD: zopen.c,v 1.1.1.1.8.1 2011/08/19 22:30:27 riz Exp $";
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -214,7 +214,7 @@
 	block_compress = maxbits & BLOCK_MASK;
 	maxbits &= BIT_MASK;
 	maxmaxcode = 1L << maxbits;
-	if (maxbits > BITS) {
+	if (maxbits > BITS || maxbits < 12) {
 		return -1;
 	}
 	/* As above, initialize the first 256 entries in the table. */
@@ -224,15 +224,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. */
-	*(zs->next_out)++ = (unsigned char)finchar;
-	zs->total_out++;
-	count--;
+	oldcode = -1;
 	stackp = de_stack;
 
 	while ((code = getcode(zs)) > -1) {
@@ -240,15 +232,19 @@
 			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. */
 		if (code >= free_ent) {
+			if (code > free_ent || oldcode == -1) {
+				/* Bad stream. */
+				errno = EINVAL;
+				return (-1);
+			}
 			*stackp++ = finchar;
 			code = oldcode;
 		}
@@ -274,7 +270,7 @@
 		} while (stackp > de_stack);
 
 		/* Generate the new entry. */
-		if ((code = free_ent) < maxmaxcode) {
+		if ((code = free_ent) < maxmaxcode && oldcode != -1) {
 			tab_prefixof(code) = (unsigned short) oldcode;
 			tab_suffixof(code) = finchar;
 			free_ent = code + 1;

Index: xsrc/xfree/xc/lib/font/fontfile/decompress.c
diff -u xsrc/xfree/xc/lib/font/fontfile/decompress.c:1.1.1.4 xsrc/xfree/xc/lib/font/fontfile/decompress.c:1.1.1.4.20.1
--- xsrc/xfree/xc/lib/font/fontfile/decompress.c:1.1.1.4	Sat Jan 19 14:58:56 2002
+++ xsrc/xfree/xc/lib/font/fontfile/decompress.c	Fri Aug 19 22:30:27 2011
@@ -96,7 +96,7 @@
 #define FIRST	257	/* first free entry */
 #define	CLEAR	256	/* table clear output code */
 
-#define STACK_SIZE  8192
+#define STACK_SIZE  65300
 
 typedef struct _compressedFILE {
     BufFilePtr	    file;
@@ -177,14 +177,12 @@
 	file->tab_suffix[code] = (char_type) code;
     }
     file->free_ent = ((file->block_compress) ? FIRST : 256 );
+    file->oldcode = -1;
     file->clear_flg = 0;
     file->offset = 0;
     file->size = 0;
     file->stackp = file->de_stack;
     bzero(file->buf, BITS);
-    file->finchar = file->oldcode = getcode (file);
-    if (file->oldcode != -1)
-	*file->stackp++ = file->finchar;
     return BufFileCreate ((char *) file,
 			  BufCompressedFill,
 			  0,
@@ -229,9 +227,6 @@
 	if (buf == bufend)
 	    break;
 
-	if (oldcode == -1)
-	    break;
-
 	code = getcode (file);
 	if (code == -1)
 	    break;
@@ -240,19 +235,29 @@
 	    for ( code = 255; code >= 0; code-- )
 	    	file->tab_prefix[code] = 0;
 	    file->clear_flg = 1;
-	    file->free_ent = FIRST - 1;
-	    if ( (code = getcode (file)) == -1 )	/* O, untimely death! */
-	    	break;
+	    file->free_ent = FIRST;
+	    oldcode = -1;
+	    continue;
     	}
     	incode = code;
     	/*
      	 * Special case for KwKwK string.
      	 */
     	if ( code >= file->free_ent ) {
+	    if ( code > file->free_ent || oldcode == -1 ) {
+		/* Bad stream. */
+		return BUFFILEEOF;
+	    }
 	    *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
      	 */
@@ -267,7 +272,7 @@
     	/*
      	 * Generate the new entry.
      	 */
-    	if ( (code=file->free_ent) < file->maxmaxcode ) {
+    	if ( (code=file->free_ent) < file->maxmaxcode && oldcode != -1) {
 	    file->tab_prefix[code] = (unsigned short)oldcode;
 	    file->tab_suffix[code] = finchar;
 	    file->free_ent = code+1;

Reply via email to