Module Name:    xsrc
Committed By:   riz
Date:           Fri Aug 19 20:54:36 UTC 2011

Modified Files:
        xsrc/external/mit/freetype/dist/src/lzw [netbsd-5]: ftzopen.c
        xsrc/external/mit/libXfont/dist/src/fontfile [netbsd-5]: decompress.c
        xsrc/xfree/xc/extras/freetype2/src/lzw [netbsd-5]: zopen.c
        xsrc/xfree/xc/lib/font/fontfile [netbsd-5]: decompress.c

Log Message:
Pull up following revision(s) (requested by joerg in ticket #1661):
        xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c: revision 1.2
        xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c: revision 1.3
        src/usr.bin/gzip/zuncompress.c: revision 1.9-1.11
        src/usr.bin/compress/zopen.c: revision 1.14-1.15
        xsrc/xfree/xc/lib/font/fontfile/decompress.c: revision 1.2
        xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c: revision 1.2
        xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c: revision 1.4
P
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.2.1 -r1.1.1.1.2.2 \
    xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c
cvs rdiff -u -r1.1.1.1.2.1 -r1.1.1.1.2.2 \
    xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.10.1 \
    xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.22.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/external/mit/freetype/dist/src/lzw/ftzopen.c
diff -u xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c:1.1.1.1.2.1 xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c:1.1.1.1.2.2
--- xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c:1.1.1.1.2.1	Thu Jul  2 05:08:09 2009
+++ xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c	Fri Aug 19 20:54:36 2011
@@ -266,7 +266,7 @@
         state->block_mode = max_bits & LZW_BLOCK_MASK;
         state->max_free   = (FT_UInt)( ( 1UL << state->max_bits ) - 256 );
 
-        if ( state->max_bits > LZW_MAX_BITS )
+        if ( state->max_bits > LZW_MAX_BITS || state->max_bits < 12)
           goto Eof;
 
         state->num_bits = LZW_INIT_BITS;
@@ -277,19 +277,7 @@
         state->free_bits = state->num_bits < state->max_bits
                            ? (FT_UInt)( ( 1UL << state->num_bits ) - 256 )
                            : state->max_free + 1;
-
-        c = ft_lzwstate_get_code( state );
-        if ( c < 0 )
-          goto Eof;
-
-        old_code = old_char = (FT_UInt)c;
-
-        if ( buffer )
-          buffer[result] = (FT_Byte)old_char;
-
-        if ( ++result >= out_size )
-          goto Exit;
-
+        old_code = -1;
         state->phase = FT_LZW_PHASE_CODE;
       }
       /* fall-through */
@@ -309,14 +297,10 @@
 
         if ( code == LZW_CLEAR && state->block_mode )
         {
-          /* why not LZW_FIRST-256 ? */
-          state->free_ent  = ( LZW_FIRST - 1 ) - 256;
+          state->free_ent  = LZW_FIRST - 256;
           state->buf_clear = 1;
-          c = ft_lzwstate_get_code( state );
-          if ( c < 0 )
-            goto Eof;
-
-          code = (FT_UInt)c;
+          old_code = -1;
+          goto NextCode;
         }
 
         in_code = code; /* save code for later */
@@ -326,6 +310,8 @@
           /* special case for KwKwKwK */
           if ( code - 256U >= state->free_ent )
           {
+            if ( code - 256U > state->free_ent )
+              goto Eof; /* Broken stream */
             FTLZW_STACK_PUSH( old_char );
             code = old_code;
           }
@@ -361,7 +347,7 @@
         }
 
         /* now create new entry */
-        if ( state->free_ent < state->max_free )
+        if ( state->free_ent < state->max_free && old_code != -1)
         {
           if ( state->free_ent >= state->prefix_size &&
                ft_lzwstate_prefix_grow( state ) < 0  )

Index: xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c
diff -u xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c:1.1.1.1.2.1 xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c:1.1.1.1.2.2
--- xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c:1.1.1.1.2.1	Thu Sep 17 03:33:15 2009
+++ xsrc/external/mit/libXfont/dist/src/fontfile/decompress.c	Fri Aug 19 20:54:36 2011
@@ -99,7 +99,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;
@@ -180,14 +180,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,
@@ -232,9 +230,6 @@
 	if (buf == bufend)
 	    break;
 
-	if (oldcode == -1)
-	    break;
-
 	code = getcode (file);
 	if (code == -1)
 	    break;
@@ -243,19 +238,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
      	 */
@@ -270,7 +275,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;

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.10.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 20:54:36 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.10.1 2011/08/19 20:54:36 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.10.1 2011/08/19 20:54:36 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.22.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 20:54:36 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