Module Name:    xsrc
Committed By:   mrg
Date:           Wed May 13 17:08:24 UTC 2009

Modified Files:
        xsrc/external/mit/freetype/dist/src/cff: cffload.c
        xsrc/external/mit/freetype/dist/src/lzw: ftzopen.c
        xsrc/external/mit/freetype/dist/src/sfnt: ttcmap.c
        xsrc/external/mit/freetype/dist/src/smooth: ftsmooth.c

Log Message:
apply fixes from CVE-2009-0946:

Description
Multiple integer overflows in FreeType 2.3.9 and earlier allow
remote attackers to execute arbitrary code via vectors related
to large values in certain inputs in (1) smooth/ftsmooth.c,
(2) sfnt/ttcmap.c, and (3) cff/cffload.c.

# 
CONFIRM:http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=0545ec1ca36b27cb928128870a83e5f668980bc5
# 
CONFIRM:http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=79972af4f0485a11dcb19551356c45245749fc5b
# 
CONFIRM:http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=a18788b14db60ae3673f932249cd02d33a227c4e

plus: 
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=0a05ba257b6ddd87dacf8d54b626e4b360e0a596

Problem reported by Tavis Ormandy <[email protected]>.
* src/lsw/ftzopen.c (ft_lzwstate_io): Test whether `state->prefix' is zero.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.2 -r1.2 \
    xsrc/external/mit/freetype/dist/src/cff/cffload.c
cvs rdiff -u -r1.1.1.1 -r1.2 \
    xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c
cvs rdiff -u -r1.1.1.2 -r1.2 \
    xsrc/external/mit/freetype/dist/src/sfnt/ttcmap.c
cvs rdiff -u -r1.1.1.2 -r1.2 \
    xsrc/external/mit/freetype/dist/src/smooth/ftsmooth.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/cff/cffload.c
diff -u xsrc/external/mit/freetype/dist/src/cff/cffload.c:1.1.1.2 xsrc/external/mit/freetype/dist/src/cff/cffload.c:1.2
--- xsrc/external/mit/freetype/dist/src/cff/cffload.c:1.1.1.2	Mon Apr 13 18:50:15 2009
+++ xsrc/external/mit/freetype/dist/src/cff/cffload.c	Wed May 13 17:08:24 2009
@@ -842,7 +842,20 @@
             goto Exit;
 
           for ( j = 1; j < num_glyphs; j++ )
-            charset->sids[j] = FT_GET_USHORT();
+          {
+            FT_UShort sid = FT_GET_USHORT();
+
+
+            /* this constant is given in the CFF specification */
+            if ( sid < 65000 )
+              charset->sids[j] = sid;
+            else
+            {
+              FT_ERROR(( "cff_charset_load:"
+                         " invalid SID value %d set to zero\n", sid ));
+              charset->sids[j] = 0;
+            }
+          }
 
           FT_FRAME_EXIT();
         }
@@ -875,6 +888,20 @@
                 goto Exit;
             }
 
+            /* check whether the range contains at least one valid glyph; */
+            /* the constant is given in the CFF specification             */
+            if ( glyph_sid >= 65000 ) {
+              FT_ERROR(( "cff_charset_load: invalid SID range\n" ));
+              error = CFF_Err_Invalid_File_Format;
+              goto Exit;
+            }
+
+            /* try to rescue some of the SIDs if `nleft' is too large */
+            if ( nleft > 65000 - 1 || glyph_sid >= 65000 - nleft ) {
+              FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" ));
+              nleft = 65000 - 1 - glyph_sid;
+            }
+
             /* Fill in the range of sids -- `nleft + 1' glyphs. */
             for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
               charset->sids[j] = glyph_sid;

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 xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c:1.2
--- xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c:1.1.1.1	Wed Jul 30 02:36:13 2008
+++ xsrc/external/mit/freetype/dist/src/lzw/ftzopen.c	Wed May 13 17:08:24 2009
@@ -332,6 +332,9 @@
 
           while ( code >= 256U )
           {
+            if ( !state->prefix )
+              goto Eof;
+
             FTLZW_STACK_PUSH( state->suffix[code - 256] );
             code = state->prefix[code - 256];
           }

Index: xsrc/external/mit/freetype/dist/src/sfnt/ttcmap.c
diff -u xsrc/external/mit/freetype/dist/src/sfnt/ttcmap.c:1.1.1.2 xsrc/external/mit/freetype/dist/src/sfnt/ttcmap.c:1.2
--- xsrc/external/mit/freetype/dist/src/sfnt/ttcmap.c:1.1.1.2	Mon Apr 13 18:49:39 2009
+++ xsrc/external/mit/freetype/dist/src/sfnt/ttcmap.c	Wed May 13 17:08:24 2009
@@ -1635,7 +1635,7 @@
       FT_INVALID_TOO_SHORT;
 
     length = TT_NEXT_ULONG( p );
-    if ( table + length > valid->limit || length < 8208 )
+    if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
       FT_INVALID_TOO_SHORT;
 
     is32       = table + 12;
@@ -1863,7 +1863,8 @@
     p      = table + 16;
     count  = TT_NEXT_ULONG( p );
 
-    if ( table + length > valid->limit || length < 20 + count * 2 )
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 20 + count * 2                     )
       FT_INVALID_TOO_SHORT;
 
     /* check glyph indices */
@@ -2048,7 +2049,8 @@
     p          = table + 12;
     num_groups = TT_NEXT_ULONG( p );
 
-    if ( table + length > valid->limit || length < 16 + 12 * num_groups )
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 16 + 12 * num_groups               )
       FT_INVALID_TOO_SHORT;
 
     /* check groups, they must be in increasing order */
@@ -2429,7 +2431,8 @@
     FT_ULong  num_selectors = TT_NEXT_ULONG( p );
 
 
-    if ( table + length > valid->limit || length < 10 + 11 * num_selectors )
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 10 + 11 * num_selectors            )
       FT_INVALID_TOO_SHORT;
 
     /* check selectors, they must be in increasing order */
@@ -2491,7 +2494,7 @@
           FT_ULong  i, lastUni = 0;
 
 
-          if ( ndp + numMappings * 4 > valid->limit )
+          if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
             FT_INVALID_TOO_SHORT;
 
           for ( i = 0; i < numMappings; ++i )

Index: xsrc/external/mit/freetype/dist/src/smooth/ftsmooth.c
diff -u xsrc/external/mit/freetype/dist/src/smooth/ftsmooth.c:1.1.1.2 xsrc/external/mit/freetype/dist/src/smooth/ftsmooth.c:1.2
--- xsrc/external/mit/freetype/dist/src/smooth/ftsmooth.c:1.1.1.2	Mon Apr 13 18:50:28 2009
+++ xsrc/external/mit/freetype/dist/src/smooth/ftsmooth.c	Wed May 13 17:08:24 2009
@@ -153,7 +153,7 @@
       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     }
 
-    /* allocate new one, depends on pixel format */
+    /* allocate new one */
     pitch = width;
     if ( hmul )
     {
@@ -194,6 +194,13 @@
 
 #endif
 
+    if ( pitch > 0xFFFF || height > 0xFFFF )
+    {
+      FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n",
+                 width, height ));
+      return Smooth_Err_Raster_Overflow;
+    }
+
     bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
     bitmap->num_grays  = 256;
     bitmap->width      = width;

Reply via email to