[base] Check too long POST and sfnt resource (#45919).

* src/base/ftbase.h (FT_MAC_RFORK_MAX_LEN): Maximum length
of the resource fork for Mac OS.  The resource fork larger
than 16 MB can be written but could not be handled
correctly, at least in Carbon routine.
See https://support.microsoft.com/en-us/kb/130437

* src/base/ftobjs.c (Mac_Read_POST_Resource): No need `0x'
for `%p' formatter.

* src/base/ftbase.c (Mac_Read_POST_Resource): Check the
fragment and total size of the concatenated POST resource
before buffer allocation.
(Mac_Read_sfnt_Resource): Check the declared size of
sfnt resource before buffer allocation.

* src/base/ftmac.c (read_lwfn, FT_New_Face_From_SFNT):
Check the total resource size before buffer allocation.
This commit is contained in:
suzuki toshiya 2015-09-21 23:07:22 +09:00
parent 730b6d7468
commit e982f5b78a
4 changed files with 46 additions and 10 deletions

View File

@ -1,3 +1,25 @@
2015-09-21 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
[base] Check too long POST and sfnt resource (#45919).
* src/base/ftbase.h (FT_MAC_RFORK_MAX_LEN): Maximum length
of the resource fork for Mac OS. The resource fork larger
than 16 MB can be written but could not be handled
correctly, at least in Carbon routine.
See https://support.microsoft.com/en-us/kb/130437
* src/base/ftobjs.c (Mac_Read_POST_Resource): No need `0x'
for `%p' formatter.
* src/base/ftbase.c (Mac_Read_POST_Resource): Check the
fragment and total size of the concatenated POST resource
before buffer allocation.
(Mac_Read_sfnt_Resource): Check the declared size of
sfnt resource before buffer allocation.
* src/base/ftmac.c (read_lwfn, FT_New_Face_From_SFNT):
Check the total resource size before buffer allocation.
2015-09-19 Werner Lemberg <wl@gnu.org> 2015-09-19 Werner Lemberg <wl@gnu.org>
[sfnt] Improve handling of invalid SFNT table entries (#45987). [sfnt] Improve handling of invalid SFNT table entries (#45987).

View File

@ -27,6 +27,11 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
/* MacOS resource fork cannot exceed 16 MB at least for Carbon code */
/* see https://support.microsoft.com/en-us/kb/130437 */
#define FT_MAC_RFORK_MAX_LEN 0x00FFFFFFUL
/* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */
/* font, and try to load a face specified by the face_index. */ /* font, and try to load a face specified by the face_index. */
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )

View File

@ -621,8 +621,8 @@
total_size += GetHandleSize( post_data ) - 2; total_size += GetHandleSize( post_data ) - 2;
last_code = code; last_code = code;
/* detect integer overflows */ /* detect resource fork overflow */
if ( total_size < old_total_size ) if ( FT_MAC_RFORK_MAX_LEN < total_size )
{ {
error = FT_THROW( Array_Too_Large ); error = FT_THROW( Array_Too_Large );
goto Error; goto Error;
@ -747,6 +747,11 @@
return FT_THROW( Invalid_Handle ); return FT_THROW( Invalid_Handle );
sfnt_size = (FT_ULong)GetHandleSize( sfnt ); sfnt_size = (FT_ULong)GetHandleSize( sfnt );
/* detect resource fork overflow */
if ( FT_MAC_RFORK_MAX_LEN < sfnt_size )
return FT_THROW( Array_Too_Large );
if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
{ {
ReleaseResource( sfnt ); ReleaseResource( sfnt );

View File

@ -1586,12 +1586,14 @@
/* FT2 allocator takes signed long buffer length, /* FT2 allocator takes signed long buffer length,
* too large value causing overflow should be checked * too large value causing overflow should be checked
*/ */
FT_TRACE4(( " POST fragment #%d: length=0x%08x\n", FT_TRACE4(( " POST fragment #%d: length=0x%08x"
i, temp)); " total pfb_len=0x%08x\n",
if ( 0x7FFFFFFFUL < temp || pfb_len + temp + 6 < pfb_len ) i, temp, pfb_len + temp + 6));
if ( FT_MAC_RFORK_MAX_LEN < temp ||
FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 )
{ {
FT_TRACE2(( " too long fragment length makes" FT_TRACE2(( " MacOS resource length cannot exceed"
" pfb_len confused: temp=0x%08x\n", temp )); " 0x%08x\n", FT_MAC_RFORK_MAX_LEN ));
error = FT_THROW( Invalid_Offset ); error = FT_THROW( Invalid_Offset );
goto Exit; goto Exit;
} }
@ -1664,7 +1666,7 @@
else else
{ {
FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer"
" 0x%p + 0x%08x\n", i, pfb_data, pfb_lenpos )); " %p + 0x%08x\n", i, pfb_data, pfb_lenpos ));
if ( pfb_lenpos + 3 > pfb_len + 2 ) if ( pfb_lenpos + 3 > pfb_len + 2 )
goto Exit2; goto Exit2;
pfb_data[pfb_lenpos ] = (FT_Byte)( len ); pfb_data[pfb_lenpos ] = (FT_Byte)( len );
@ -1676,7 +1678,7 @@
break; break;
FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer"
" 0x%p + 0x%08x\n", i, pfb_data, pfb_pos )); " %p + 0x%08x\n", i, pfb_data, pfb_pos ));
if ( pfb_pos + 6 > pfb_len + 2 ) if ( pfb_pos + 6 > pfb_len + 2 )
goto Exit2; goto Exit2;
pfb_data[pfb_pos++] = 0x80; pfb_data[pfb_pos++] = 0x80;
@ -1696,7 +1698,7 @@
goto Exit2; goto Exit2;
FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer"
" 0x%p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos ));
error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
if ( error ) if ( error )
goto Exit2; goto Exit2;
@ -1774,6 +1776,8 @@
goto Exit; goto Exit;
if ( rlen == -1 ) if ( rlen == -1 )
return FT_THROW( Cannot_Open_Resource ); return FT_THROW( Cannot_Open_Resource );
if ( rlen > FT_MAC_RFORK_MAX_LEN )
return FT_THROW( Invalid_Offset );
error = open_face_PS_from_sfnt_stream( library, error = open_face_PS_from_sfnt_stream( library,
stream, stream,