Commit 9fa8a2997f869c6172a12a9497b3ca649806ec4d

Werner Lemberg 2017-06-04T20:43:08

[cff, truetype] Integer overflows. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2075 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2088 * src/cff/cf2font.c (cf2_font_setup): Use OVERFLOW_MUL_INT32. * src/truetype/ttinterp.c (Ins_ISECT): Use OVERFLOW_MUL_LONG, OVERFLOW_ADD_LONG, and OVERFLOW_SUB_LONG.

diff --git a/ChangeLog b/ChangeLog
index e3a42c2..7f68614 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2017-06-04  Werner Lemberg  <wl@gnu.org>
+
+	[cff, truetype] Integer overflows.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2075
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2088
+
+	* src/cff/cf2font.c (cf2_font_setup): Use OVERFLOW_MUL_INT32.
+
+	* src/truetype/ttinterp.c (Ins_ISECT): Use OVERFLOW_MUL_LONG,
+	OVERFLOW_ADD_LONG, and OVERFLOW_SUB_LONG.
+
 2017-06-03  Werner Lemberg  <wl@gnu.org>
 
 	[base, cff, truetype] Integer overflows.
diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
index 2551437..c81f938 100644
--- a/src/cff/cf2font.c
+++ b/src/cff/cf2font.c
@@ -447,7 +447,7 @@
       /* choose a constant for StdHW that depends on font contrast       */
       stdHW = cf2_getStdHW( decoder );
 
-      if ( stdHW > 0 && font->stdVW > 2 * stdHW )
+      if ( stdHW > 0 && font->stdVW > OVERFLOW_MUL_INT32( 2, stdHW ) )
         font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
       else
       {
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 85e9e08..d39504a 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -6455,19 +6455,19 @@
 
     /* Cramer's rule */
 
-    dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
-    dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
+    dbx = OVERFLOW_SUB_LONG( exc->zp0.cur[b1].x, exc->zp0.cur[b0].x );
+    dby = OVERFLOW_SUB_LONG( exc->zp0.cur[b1].y, exc->zp0.cur[b0].y );
 
-    dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
-    day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
+    dax = OVERFLOW_SUB_LONG( exc->zp1.cur[a1].x, exc->zp1.cur[a0].x );
+    day = OVERFLOW_SUB_LONG( exc->zp1.cur[a1].y, exc->zp1.cur[a0].y );
 
-    dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
-    dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
+    dx = OVERFLOW_SUB_LONG( exc->zp0.cur[b0].x, exc->zp1.cur[a0].x );
+    dy = OVERFLOW_SUB_LONG( exc->zp0.cur[b0].y, exc->zp1.cur[a0].y );
 
-    discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
-                   FT_MulDiv( day, dbx, 0x40 );
-    dotproduct   = FT_MulDiv( dax, dbx, 0x40 ) +
-                   FT_MulDiv( day, dby, 0x40 );
+    discriminant = OVERFLOW_ADD_LONG( FT_MulDiv( dax, -dby, 0x40 ),
+                                      FT_MulDiv( day, dbx, 0x40 ) );
+    dotproduct   = OVERFLOW_ADD_LONG( FT_MulDiv( dax, dbx, 0x40 ),
+                                      FT_MulDiv( day, dby, 0x40 ) );
 
     /* The discriminant above is actually a cross product of vectors     */
     /* da and db. Together with the dot product, they can be used as     */
@@ -6477,30 +6477,34 @@
     /*       discriminant = |da||db|sin(angle)     .                     */
     /* We use these equations to reject grazing intersections by         */
     /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */
-    if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) )
+    if ( OVERFLOW_MUL_LONG( 19, FT_ABS( discriminant ) ) >
+           FT_ABS( dotproduct ) )
     {
-      val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 );
+      val = OVERFLOW_ADD_LONG( FT_MulDiv( dx, -dby, 0x40 ),
+                               FT_MulDiv( dy, dbx, 0x40 ) );
 
       R.x = FT_MulDiv( val, dax, discriminant );
       R.y = FT_MulDiv( val, day, discriminant );
 
       /* XXX: Block in backward_compatibility and/or post-IUP? */
-      exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
-      exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
+      exc->zp2.cur[point].x = OVERFLOW_ADD_LONG( exc->zp1.cur[a0].x, R.x );
+      exc->zp2.cur[point].y = OVERFLOW_ADD_LONG( exc->zp1.cur[a0].y, R.y );
     }
     else
     {
       /* else, take the middle of the middles of A and B */
 
       /* XXX: Block in backward_compatibility and/or post-IUP? */
-      exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
-                                exc->zp1.cur[a1].x +
-                                exc->zp0.cur[b0].x +
-                                exc->zp0.cur[b1].x ) / 4;
-      exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
-                                exc->zp1.cur[a1].y +
-                                exc->zp0.cur[b0].y +
-                                exc->zp0.cur[b1].y ) / 4;
+      exc->zp2.cur[point].x =
+        OVERFLOW_ADD_LONG( OVERFLOW_ADD_LONG( exc->zp1.cur[a0].x,
+                                              exc->zp1.cur[a1].x ),
+                           OVERFLOW_ADD_LONG( exc->zp0.cur[b0].x,
+                                              exc->zp0.cur[b1].x ) ) / 4;
+      exc->zp2.cur[point].y =
+        OVERFLOW_ADD_LONG( OVERFLOW_ADD_LONG( exc->zp1.cur[a0].y,
+                                              exc->zp1.cur[a1].y ),
+                           OVERFLOW_ADD_LONG( exc->zp0.cur[b0].y,
+                                              exc->zp0.cur[b1].y ) ) / 4;
     }
 
     exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;