From 57c4252ab5f435c52e66b619bd514068f7a683b0 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Tue, 2 Jan 2024 17:55:33 +0100 Subject: [PATCH] [sfnt] Guard access in 'COLR' v1 glyph binary search. Reported as https://bugs.chromium.org/p/chromium/issues/detail?id=1505216 * src/sfnt/ttcolr.c (find_base_glyph_v1_record): Guard access of the search pointer during binary search. The pointer needs to be checked as we go as the test that compares number of v1 glyphs with table size at the time of loading the table is not sufficient on its own. A scenario is possible in which the `BaseGlyphRecord` list extends into non-`BaseGlyphRecord` parts of the 'COLR' v1 table (but passed the size comparison check). Then, at those locations, invalid glyph ID values are read and may provoke an invalid read due to reassigning min and max values during the binary search. --- src/sfnt/ttcolr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 281e7135e..0601d2661 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -1269,6 +1269,7 @@ static FT_Bool find_base_glyph_v1_record( FT_Byte * base_glyph_begin, FT_UInt num_base_glyph, + FT_Byte * end_colr, FT_UInt glyph_id, BaseGlyphV1Record *record ) { @@ -1287,6 +1288,14 @@ */ FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE; + + /* We need to be able to read 2 bytes (FT_NEXT_USHORT) for the glyph */ + /* ID, then 4 bytes (FT_NEXT_ULONG) for the paint offset. If that's */ + /* not available before the end of the table, something's wrong with */ + /* the font and we can't find a COLRv1 glyph. */ + if ( p > end_colr - 2 - 4 ) + return 0; + FT_UShort gid = FT_NEXT_USHORT( p ); @@ -1328,6 +1337,7 @@ if ( !find_base_glyph_v1_record( colr->base_glyphs_v1, colr->num_base_glyphs_v1, + (FT_Byte*)colr->table + colr->table_size, base_glyph, &base_glyph_v1_record ) ) return 0;