Hi,

Joerg Sonnenberger and Thomas Hoger came out with a better patch...
This brings libXfont in line with what was committed to NetBSD.

>From ff9a52ff9c65759d7c6726e445e83450b46ce6e1 Mon Sep 17 00:00:00 2001
From: Joerg Sonnenberger <[email protected]>
Date: Sun, 21 Aug 2011 18:51:53 +0200
Subject: [PATCH libXfont] Do proper input validation to fix for
 CVE-2011-2895.

It ensures that all valid input can be decompressed, checks that the
overflow conditions doesn't happen and generally tightens the
validation of the LZW stream and doesn't pessimize the inner loop for
no good reason. It's derived from a change in libarchive from 2004.

Signed-off-by: Matthieu Herrb <[email protected]>
Reviewed-by: Tomas Hoger <[email protected]>
---
 src/fontfile/decompress.c |   31 +++++++++++++++++--------------
 1 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/fontfile/decompress.c b/src/fontfile/decompress.c
index c8171dd..81896aa 100644
--- a/src/fontfile/decompress.c
+++ b/src/fontfile/decompress.c
@@ -97,7 +97,7 @@ static char_type magic_header[] = { "\037\235" };     /* 1F 
9D */
 #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;
@@ -178,14 +178,12 @@ BufFilePushCompressed (BufFilePtr f)
        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,
@@ -230,9 +228,6 @@ BufCompressedFill (BufFilePtr f)
        if (buf == bufend)
            break;
 
-       if (oldcode == -1)
-           break;
-
        code = getcode (file);
        if (code == -1)
            break;
@@ -241,26 +236,34 @@ BufCompressedFill (BufFilePtr f)
            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
         */
        while ( code >= 256 )
        {
-           if (stackp - de_stack >= STACK_SIZE - 1)
-               return BUFFILEEOF;
            *stackp++ = file->tab_suffix[code];
            code = file->tab_prefix[code];
        }
@@ -270,7 +273,7 @@ BufCompressedFill (BufFilePtr f)
        /*
         * 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;
-- 
1.7.6


-- 
Matthieu Herrb
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to