Sophie

Sophie

distrib > Mandriva > 2010.2 > i586 > media > main-updates-src > by-pkgid > a6c468d5fa3408dbd88ed90cd40665e9 > files > 22

freetype2-2.3.12-1.9mdv2010.2.src.rpm

This patch includes backports of the following
git commits:

CVE-2010-2497 freetype integer underflow #30082 #30083
7d3d2cc4fef72c6be9c454b3809c387e12b44cfc 

CVE-2010-2498 freetype invalid free #30106
8d22746c9e5af80ff4304aef440986403a5072e2

CVE-2010-2499 freetype buffer overflow #30248 #30249
c69891a1345640096fbf396e8dd567fe879ce233
f29f741efbba0a5ce2f16464f648fb8d026ed4c8

CVE-2010-2500 freetype integer overflow #30263
6305b869d86ff415a33576df6d43729673c66eee
1c70fcbc0aab13aed5bfe757553d0bbe6ab9461c

CVE-2010-2519 freetype heap buffer overflow #30306
5ef20c8c1d4de12a84b50ba497c2a358c90ec44b
b2ea64bcc6c385a8e8318f9c759450a07df58b6d

diff -Naur freetype-2.3.12/src/base/ftobjs.c freetype-2.3.12.oden/src/base/ftobjs.c
--- freetype-2.3.12/src/base/ftobjs.c	2010-01-23 13:44:16.000000000 +0100
+++ freetype-2.3.12.oden/src/base/ftobjs.c	2010-07-18 15:56:25.080809430 +0200
@@ -1548,11 +1548,25 @@
         goto Exit;
       if ( FT_READ_USHORT( flags ) )
         goto Exit;
-      rlen -= 2;                    /* the flags are part of the resource */
+      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
+                   i, offsets[i], rlen, flags ));
+
+      if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
+        continue;
+
+      /* the flags are part of the resource, so rlen >= 2.  */
+      /* but some fonts declare rlen = 0 for empty fragment */
+      if ( rlen > 2 )
+        rlen -= 2;
+      else
+        rlen = 0;
+
       if ( ( flags >> 8 ) == type )
         len += rlen;
       else
       {
+        if ( pfb_lenpos + 3 > pfb_len + 2 )
+          goto Exit2;
         pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
         pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
         pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
@@ -1561,6 +1575,8 @@
         if ( ( flags >> 8 ) == 5 )      /* End of font mark */
           break;
 
+        if ( pfb_pos + 6 > pfb_len + 2 )
+          goto Exit2;
         pfb_data[pfb_pos++] = 0x80;
 
         type = flags >> 8;
@@ -1575,12 +1591,18 @@
       }
 
       error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
+      if ( error )
+        goto Exit2;
       pfb_pos += rlen;
     }
 
+    if ( pfb_pos + 2 > pfb_len + 2 )
+      goto Exit2;
     pfb_data[pfb_pos++] = 0x80;
     pfb_data[pfb_pos++] = 3;
 
+    if ( pfb_lenpos + 3 > pfb_len + 2 )
+      goto Exit2;
     pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
     pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
     pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
diff -Naur freetype-2.3.12/src/cff/cffgload.c freetype-2.3.12.oden/src/cff/cffgload.c
--- freetype-2.3.12/src/cff/cffgload.c	2010-02-10 07:08:08.000000000 +0100
+++ freetype-2.3.12.oden/src/cff/cffgload.c	2010-07-18 15:56:37.591225654 +0200
@@ -2276,6 +2276,8 @@
           /* this is the implementation described for `unknown' other  */
           /* subroutines in the Type1 spec.                            */
           args -= 2 + ( args[-2] >> 16 );
+          if ( args < stack )
+            goto Stack_Underflow;
           break;
 
         case cff_op_pop:
diff -Naur freetype-2.3.12/src/pfr/pfrgload.c freetype-2.3.12.oden/src/pfr/pfrgload.c
--- freetype-2.3.12/src/pfr/pfrgload.c	2009-03-14 14:45:26.000000000 +0100
+++ freetype-2.3.12.oden/src/pfr/pfrgload.c	2010-07-18 15:56:25.090799365 +0200
@@ -268,8 +268,8 @@
     {
       PFR_CHECK( 1 );
       count   = PFR_NEXT_BYTE( p );
-      x_count = ( count & 15 );
-      y_count = ( count >> 4 );
+      x_count = count & 15;
+      y_count = count >> 4;
     }
     else
     {
@@ -388,7 +388,7 @@
 
         case 2:                             /* horizontal line to */
           FT_TRACE6(( "- horizontal line to cx.%d", format_low ));
-          if ( format_low > x_count )
+          if ( format_low >= x_count )
             goto Failure;
           pos[0].x   = glyph->x_control[format_low];
           pos[0].y   = pos[3].y;
@@ -398,7 +398,7 @@
 
         case 3:                             /* vertical line to */
           FT_TRACE6(( "- vertical line to cy.%d", format_low ));
-          if ( format_low > y_count )
+          if ( format_low >= y_count )
             goto Failure;
           pos[0].x   = pos[3].x;
           pos[0].y   = glyph->y_control[format_low];
@@ -440,7 +440,7 @@
           case 0:                           /* 8-bit index */
             PFR_CHECK( 1 );
             idx  = PFR_NEXT_BYTE( p );
-            if ( idx > x_count )
+            if ( idx >= x_count )
               goto Failure;
             cur->x = glyph->x_control[idx];
             FT_TRACE7(( " cx#%d", idx ));
@@ -470,7 +470,7 @@
           case 0:                           /* 8-bit index */
             PFR_CHECK( 1 );
             idx  = PFR_NEXT_BYTE( p );
-            if ( idx > y_count )
+            if ( idx >= y_count )
               goto Failure;
             cur->y = glyph->y_control[idx];
             FT_TRACE7(( " cy#%d", idx ));
diff -Naur freetype-2.3.12/src/pshinter/pshalgo.c freetype-2.3.12.oden/src/pshinter/pshalgo.c
--- freetype-2.3.12/src/pshinter/pshalgo.c	2009-07-03 15:28:24.000000000 +0200
+++ freetype-2.3.12.oden/src/pshinter/pshalgo.c	2010-07-18 15:56:25.090799365 +0200
@@ -1690,7 +1690,10 @@
     /* process secondary hints to `selected' points */
     if ( num_masks > 1 && glyph->num_points > 0 )
     {
-      first = mask->end_point;
+      /* the `endchar' op can reduce the number of points */
+      first = mask->end_point > glyph->num_points
+                ? glyph->num_points
+                : mask->end_point;
       mask++;
       for ( ; num_masks > 1; num_masks--, mask++ )
       {
@@ -1698,7 +1701,9 @@
         FT_Int   count;
 
 
-        next  = mask->end_point;
+        next  = mask->end_point > glyph->num_points
+                  ? glyph->num_points
+                  : mask->end_point;
         count = next - first;
         if ( count > 0 )
         {
diff -Naur freetype-2.3.12/src/smooth/ftgrays.c freetype-2.3.12.oden/src/smooth/ftgrays.c
--- freetype-2.3.12/src/smooth/ftgrays.c	2009-07-31 18:45:19.000000000 +0200
+++ freetype-2.3.12.oden/src/smooth/ftgrays.c	2010-07-18 15:56:25.090799365 +0200
@@ -1007,45 +1007,40 @@
                               const FT_Vector*  control2,
                               const FT_Vector*  to )
   {
-    TPos        dx, dy, da, db;
+    TPos        dx, dy;
+    TPos        mid_x, mid_y;
     int         top, level;
     int*        levels;
     FT_Vector*  arc;
 
 
-    dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
-    if ( dx < 0 )
-      dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
-    if ( dy < 0 )
-      dy = -dy;
-    if ( dx < dy )
-      dx = dy;
-    da = dx;
+    /* Calculate midpoint and compare it with start and end. */
+    mid_x = ( DOWNSCALE( ras.x ) + to->x +
+              3 * ( control1->x + control2->x ) ) / 8;
+    mid_y = ( DOWNSCALE( ras.y ) + to->y +
+              3 * ( control1->y + control2->y ) ) / 8;
 
-    dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
+    dx = DOWNSCALE( ras.x ) + to->x - ( mid_x << 1 );
     if ( dx < 0 )
       dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
+    dy = DOWNSCALE( ras.y ) + to->y - ( mid_y << 1 );
     if ( dy < 0 )
       dy = -dy;
     if ( dx < dy )
       dx = dy;
-    db = dx;
 
+    /* Check whether an approximation with straight lines is sufficient. */
     level = 1;
-    da    = da / ras.cubic_level;
-    db    = db / ras.conic_level;
-    while ( da > 0 || db > 0 )
+    dx    = dx / ras.conic_level;
+    while ( dx > 0 )
     {
-      da >>= 2;
-      db >>= 3;
+      dx >>= 3;
       level++;
     }
 
     if ( level <= 1 )
     {
-      TPos   to_x, to_y, mid_x, mid_y;
+      TPos   to_x, to_y;
 
 
       to_x  = UPSCALE( to->x );
@@ -1104,7 +1099,7 @@
 
     Draw:
       {
-        TPos  to_x, to_y, mid_x, mid_y;
+        TPos  to_x, to_y;
 
 
         to_x  = arc[0].x;
@@ -1189,7 +1184,7 @@
     /* first of all, compute the scanline offset */
     p = (unsigned char*)map->buffer - y * map->pitch;
     if ( map->pitch >= 0 )
-      p += ( map->rows - 1 ) * map->pitch;
+      p += (unsigned)( ( map->rows - 1 ) * map->pitch );
 
     for ( ; count > 0; count--, spans++ )
     {
diff -Naur freetype-2.3.12/src/smooth/ftsmooth.c freetype-2.3.12.oden/src/smooth/ftsmooth.c
--- freetype-2.3.12/src/smooth/ftsmooth.c	2009-07-31 18:45:19.000000000 +0200
+++ freetype-2.3.12.oden/src/smooth/ftsmooth.c	2010-07-18 16:07:09.161438297 +0200
@@ -200,7 +200,7 @@
 
     /* Required check is ( pitch * height < FT_ULONG_MAX ),     */
     /* but we care realistic cases only. Always pitch <= width. */
-    if ( width > 0xFFFFU || height > 0xFFFFU )
+    if ( width > 0x7FFFU || height > 0x7FFFU )
     {
       FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n",
                  width, height ));