From addb2dddb6fd4be32ea16b44831e4cc99bbc9693 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sat, 3 Jun 2017 21:05:42 +0200 Subject: [base, cff, truetype] Integer overflows. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2060 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2062 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2063 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2068 * src/base/ftobjs.c (ft_glyphslot_grid_fit_metrics): Use OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. * src/cff/cf2blues.c (cf2_blues_capture), src/cff/cf2hints.c (cf2_hintmap_adjustHints): Use OVERFLOW_SUB_INT32. * src/truetype/ttgload.c (compute_glyph_metrics): User OVERFLOW_SUB_LONG. * src/truetype/ttinterp.c (Direct_Move, Direct_Move_Orig, Direct_Move_X, Direct_Move_Y, Direct_Move_Orig_X, Direct_Move_Orig_Y, Move_Zp2_Point, Ins_MSIRP): Use OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. --- ChangeLog | 27 +++++++++++++++++++++++- src/base/ftobjs.c | 24 ++++++++++++++------- src/cff/cf2blues.c | 3 ++- src/cff/cf2hints.c | 12 +++++++---- src/truetype/ttgload.c | 7 ++++--- src/truetype/ttinterp.c | 56 ++++++++++++++++++++++++++++++++----------------- 6 files changed, 93 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index f36748ca0..e3a42c226 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2017-06-03 Werner Lemberg + + [base, cff, truetype] Integer overflows. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2060 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2062 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2063 + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2068 + + * src/base/ftobjs.c (ft_glyphslot_grid_fit_metrics): Use + OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. + + * src/cff/cf2blues.c (cf2_blues_capture), src/cff/cf2hints.c + (cf2_hintmap_adjustHints): Use OVERFLOW_SUB_INT32. + + * src/truetype/ttgload.c (compute_glyph_metrics): User + OVERFLOW_SUB_LONG. + + * src/truetype/ttinterp.c (Direct_Move, Direct_Move_Orig, + Direct_Move_X, Direct_Move_Y, Direct_Move_Orig_X, + Direct_Move_Orig_Y, Move_Zp2_Point, Ins_MSIRP): Use + OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG. + 2017-06-03 Werner Lemberg * builds/unix/freetype-config.in: Fix pkg-config test (#51162). @@ -2855,7 +2880,7 @@ [cff] Implement CFF2 support (2/2). The font variation code. All parts dependent on the GX code in the - `truetype' module are guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. + `truetype' module are guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT. In other words, you can still compile the `cff' module without defining TT_CONFIG_OPTION_GX_VAR_SUPPORT (which brings you CFF2 support without font variation). diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 75e498890..cd5874c9d 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -581,28 +581,36 @@ metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); - right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); - bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); + right = FT_PIX_CEIL( OVERFLOW_ADD_LONG( metrics->vertBearingX, + metrics->width ) ); + bottom = FT_PIX_CEIL( OVERFLOW_ADD_LONG( metrics->vertBearingY, + metrics->height ) ); metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - metrics->width = right - metrics->vertBearingX; - metrics->height = bottom - metrics->vertBearingY; + metrics->width = OVERFLOW_SUB_LONG( right, + metrics->vertBearingX ); + metrics->height = OVERFLOW_SUB_LONG( bottom, + metrics->vertBearingY ); } else { metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); - bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); + right = FT_PIX_CEIL ( OVERFLOW_ADD_LONG( metrics->horiBearingX, + metrics->width ) ); + bottom = FT_PIX_FLOOR( OVERFLOW_SUB_LONG( metrics->horiBearingY, + metrics->height ) ); metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); - metrics->width = right - metrics->horiBearingX; - metrics->height = metrics->horiBearingY - bottom; + metrics->width = OVERFLOW_SUB_LONG( right, + metrics->horiBearingX ); + metrics->height = OVERFLOW_SUB_LONG( metrics->horiBearingY, + bottom ); } metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); diff --git a/src/cff/cf2blues.c b/src/cff/cf2blues.c index 950c71473..a94254d82 100644 --- a/src/cff/cf2blues.c +++ b/src/cff/cf2blues.c @@ -502,7 +502,8 @@ if ( blues->suppressOvershoot ) dsNew = blues->zone[i].dsFlatEdge; - else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >= + else if ( OVERFLOW_SUB_INT32( blues->zone[i].csTopEdge, + bottomHintEdge->csCoord ) >= blues->blueShift ) { /* guarantee minimum of 1 pixel overshoot */ diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c index 89af2ff7a..d7938c9c6 100644 --- a/src/cff/cf2hints.c +++ b/src/cff/cf2hints.c @@ -512,8 +512,10 @@ if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord ) hintmap->edge[i - 1].scale = FT_DivFix( - hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord, - hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord ); + OVERFLOW_SUB_INT32( hintmap->edge[i].dsCoord, + hintmap->edge[i - 1].dsCoord ), + OVERFLOW_SUB_INT32( hintmap->edge[i].csCoord, + hintmap->edge[i - 1].csCoord ) ); } if ( isPair ) @@ -521,8 +523,10 @@ if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord ) hintmap->edge[j - 1].scale = FT_DivFix( - hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord, - hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord ); + OVERFLOW_SUB_INT32( hintmap->edge[j].dsCoord, + hintmap->edge[j - 1].dsCoord ), + OVERFLOW_SUB_INT32( hintmap->edge[j].csCoord, + hintmap->edge[j - 1].csCoord ) ); i += 1; /* skip upper edge on next loop */ } diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index e5a3da37a..66e8228d3 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -2100,8 +2100,8 @@ } /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; + glyph->metrics.width = OVERFLOW_SUB_LONG( bbox.xMax, bbox.xMin ); + glyph->metrics.height = OVERFLOW_SUB_LONG( bbox.yMax, bbox.yMin ); /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), */ @@ -2137,7 +2137,8 @@ /* table in the font. Otherwise, we use the */ /* values defined in the horizontal header. */ - height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin, + height = (FT_Short)FT_DivFix( OVERFLOW_SUB_LONG( bbox.yMax, + bbox.yMin ), y_scale ); if ( face->os2.version != 0xFFFFU ) advance = (FT_Pos)( face->os2.sTypoAscender - diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index cbb754094..85e9e0823 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -1676,7 +1676,9 @@ if ( SUBPIXEL_HINTING_INFINALITY && ( !exc->ignore_x_mode || ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) - zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].x = OVERFLOW_ADD_LONG( + zone->cur[point].x, + FT_MulDiv( distance, v, exc->F_dot_P ) ); else #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -1685,12 +1687,16 @@ /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ /* diagonal stems like on `Z' and `z' post-IUP. */ if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) - zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].x = OVERFLOW_ADD_LONG( + zone->cur[point].x, + FT_MulDiv( distance, v, exc->F_dot_P ) ); else #endif if ( NO_SUBPIXEL_HINTING ) - zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].x = OVERFLOW_ADD_LONG( + zone->cur[point].x, + FT_MulDiv( distance, v, exc->F_dot_P ) ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1705,7 +1711,9 @@ exc->iupx_called && exc->iupy_called ) ) #endif - zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].y = OVERFLOW_ADD_LONG( + zone->cur[point].y, + FT_MulDiv( distance, v, exc->F_dot_P ) ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1741,12 +1749,16 @@ v = exc->GS.freeVector.x; if ( v != 0 ) - zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->org[point].x = OVERFLOW_ADD_LONG( + zone->org[point].x, + FT_MulDiv( distance, v, exc->F_dot_P ) ); v = exc->GS.freeVector.y; if ( v != 0 ) - zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->org[point].y = OVERFLOW_ADD_LONG( + zone->org[point].y, + FT_MulDiv( distance, v, exc->F_dot_P ) ); } @@ -1769,18 +1781,18 @@ { #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) - zone->cur[point].x += distance; + zone->cur[point].x = OVERFLOW_ADD_LONG( zone->cur[point].x, distance ); else #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) - zone->cur[point].x += distance; + zone->cur[point].x = OVERFLOW_ADD_LONG( zone->cur[point].x, distance ); else #endif if ( NO_SUBPIXEL_HINTING ) - zone->cur[point].x += distance; + zone->cur[point].x = OVERFLOW_ADD_LONG( zone->cur[point].x, distance ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1799,7 +1811,7 @@ exc->backward_compatibility && exc->iupx_called && exc->iupy_called ) ) #endif - zone->cur[point].y += distance; + zone->cur[point].y = OVERFLOW_ADD_LONG( zone->cur[point].y, distance ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1823,7 +1835,7 @@ { FT_UNUSED( exc ); - zone->org[point].x += distance; + zone->org[point].x = OVERFLOW_ADD_LONG( zone->org[point].x, distance ); } @@ -1835,7 +1847,7 @@ { FT_UNUSED( exc ); - zone->org[point].y += distance; + zone->org[point].y = OVERFLOW_ADD_LONG( zone->org[point].y, distance ); } @@ -5392,7 +5404,8 @@ if ( !( SUBPIXEL_HINTING_MINIMAL && exc->backward_compatibility ) ) #endif - exc->zp2.cur[point].x += dx; + exc->zp2.cur[point].x = OVERFLOW_ADD_LONG( exc->zp2.cur[point].x, + dx ); if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; @@ -5406,7 +5419,8 @@ exc->iupx_called && exc->iupy_called ) ) #endif - exc->zp2.cur[point].y += dy; + exc->zp2.cur[point].y = OVERFLOW_ADD_LONG( exc->zp2.cur[point].y, + dy ); if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; @@ -5781,14 +5795,18 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - FT_ABS( distance - args[1] ) >= control_value_cutin ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + FT_ABS( OVERFLOW_SUB_LONG( distance, + args[1] ) ) >= control_value_cutin ) distance = args[1]; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->func_move( exc, &exc->zp1, point, args[1] - distance ); + exc->func_move( exc, + &exc->zp1, + point, + OVERFLOW_SUB_LONG( args[1], distance ) ); exc->GS.rp1 = exc->GS.rp0; exc->GS.rp2 = point; -- cgit v1.2.1