From 9fa8a2997f869c6172a12a9497b3ca649806ec4d Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sun, 4 Jun 2017 20:43:08 +0200 Subject: [PATCH] [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. --- ChangeLog | 14 ++++++++++++ src/cff/cf2font.c | 2 +- src/truetype/ttinterp.c | 48 ++++++++++++++++++++++------------------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3a42c226..7f68614ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2017-06-04 Werner Lemberg + + [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 [base, cff, truetype] Integer overflows. diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c index 25514373b..c81f93845 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 85e9e0823..d39504a26 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;