Wed 12 Nov 2014 02:07:40 PM UTC, original submission:
In the freetype/src/sfnt/ttcmap.c file, we can find functions responsible for handling the "cmap" SFNT table (http://www.microsoft.com/typography/otspec/cmap.htm) in different formats (0, 2, 4, 6, 8, 10, 12, 13, 14). Multiple integer overflow conditions exist in the code if it is compiled for 32-bit architectures (i.e. when sizeof(long) = 4), see:
----------------------------------------------------------------------------------------------
1670: num_groups = TT_NEXT_ULONG( p );
1671:
1672: if ( p + num_groups * 12 > valid->limit )
1673: FT_INVALID_TOO_SHORT;
----------------------------------------------------------------------------------------------
1685: start = TT_NEXT_ULONG( p );
1686: end = TT_NEXT_ULONG( p );
1687: start_id = TT_NEXT_ULONG( p );
...
1697: if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
1698: FT_INVALID_GLYPH_ID;
----------------------------------------------------------------------------------------------
1884: FT_ULong length, count;
...
1892: count = TT_NEXT_ULONG( p );
...
1895: length < 20 + count * 2 )
----------------------------------------------------------------------------------------------
2069: FT_ULong num_groups;
...
2079: num_groups = TT_NEXT_ULONG( p );
...
2082: length < 16 + 12 * num_groups )
----------------------------------------------------------------------------------------------
2087: FT_ULong n, start, end, start_id, last = 0;
...
2092: start = TT_NEXT_ULONG( p );
2093: end = TT_NEXT_ULONG( p );
2094: start_id = TT_NEXT_ULONG( p );
...
2104: if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
----------------------------------------------------------------------------------------------
2391: FT_ULong num_groups;
...
2401: num_groups = TT_NEXT_ULONG( p );
...
2404: length < 16 + 12 * num_groups )
----------------------------------------------------------------------------------------------
2779: FT_ULong num_selectors;
...
2787: num_selectors = TT_NEXT_ULONG( p );
...
2790: length < 10 + 11 * num_selectors )
2821: FT_ULong numRanges = TT_NEXT_ULONG( defp );
...
2826: if ( defp + numRanges * 4 > valid->limit )
2849: FT_ULong numMappings = TT_NEXT_ULONG( ndp );
...
2853: if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
----------------------------------------------------------------------------------------------
All of the above stem from arithmetic operations (addition and multiplication) performed over fully controlled 32-bit variables, whose size is not previously sanitized in any way. This can be used to bypass the different checks in tt_cmap{8, 10, 12, 13, 14}_validate functions and consequently lead to out-of-bounds reads in those functions.
Since these issues occur in "_validate" routines responsible for ensuring that the input file is correctly formatted, it is possible that some other code which later touches the data assumes its validity (not necessarily true due to the issues explained here), which may lead to consequences more severe than out-of-bounds read, such as buffer overflows or other memory corruption. This, however, has not been confirmed.
|