[cff] Fix memory overflow. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9869 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10869 * src/cff/cffparse.c (destruct_t2s_item, cff_parser_run): Store evaluated T2 charstrings in separately allocated memory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
diff --git a/ChangeLog b/ChangeLog
index 55d2217..7efabc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-11-22 Armin Hasitzka <prince.cherusker@gmail.com>
+
+ [cff] Fix memory overflow.
+
+ Reported as
+
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9869
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10869
+
+ * src/cff/cffparse.c (destruct_t2s_item, cff_parser_run): Store
+ evaluated T2 charstrings in separately allocated memory.
+
2018-11-18 Alexei Podtelezhnikov <apodtele@gmail.com>
* builds/windows/{visualc,vc2005,vc2008}/freetype.vcproj: Fix it.
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index b8b7818..d7ff16c 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -1121,21 +1121,35 @@
#endif /* FT_DEBUG_LEVEL_TRACE */
+ static void
+ destruct_t2s_item( FT_Memory memory,
+ void* data,
+ void* user )
+ {
+ FT_UNUSED( user );
+ memory->free( memory, data );
+ }
+
+
FT_LOCAL_DEF( FT_Error )
cff_parser_run( CFF_Parser parser,
FT_Byte* start,
FT_Byte* limit )
{
+ FT_Byte* p = start;
+ FT_Error error = FT_Err_Ok;
+
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
PSAux_Service psaux;
-#endif
- FT_Byte* p = start;
- FT_Error error = FT_Err_Ok;
FT_Library library = parser->library;
+ FT_Memory memory = library->memory;
+
+ FT_ListRec t2s;
- FT_UNUSED( library );
+ FT_ZERO( &t2s );
+#endif
parser->top = parser->stack;
parser->start = start;
@@ -1195,8 +1209,9 @@
FT_Byte* charstring_base;
FT_ULong charstring_len;
- FT_Fixed* stack;
- FT_Byte* q;
+ FT_Fixed* stack;
+ FT_ListNode node;
+ FT_Byte* q;
charstring_base = ++p;
@@ -1237,13 +1252,23 @@
/* Now copy the stack data in the temporary decoder object, */
/* converting it back to charstring number representations */
/* (this is ugly, I know). */
- /* */
- /* We overwrite the original top DICT charstring under the */
- /* assumption that the charstring representation of the result */
- /* of `cff_decoder_parse_charstrings' is shorter, which should */
- /* be always true. */
- q = charstring_base - 1;
+ node = (FT_ListNode)memory->alloc( memory,
+ sizeof ( FT_ListNodeRec ) );
+ if ( !node )
+ goto Out_Of_Memory_Error;
+
+ /* `5' is the conservative upper bound of required bytes per stack */
+ /* element. */
+ q = (FT_Byte*)memory->alloc( memory,
+ 5 * ( decoder.top - decoder.stack ) );
+ if ( !q )
+ goto Out_Of_Memory_Error;
+
+ node->data = q;
+
+ FT_List_Add( &t2s, node );
+
stack = decoder.stack;
while ( stack < decoder.top )
@@ -1500,11 +1525,18 @@
parser->top = parser->stack;
}
p++;
- }
+ } /* while ( p < limit ) */
Exit:
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL );
+#endif
return error;
+ Out_Of_Memory_Error:
+ error = FT_THROW( Out_Of_Memory );
+ goto Exit;
+
Stack_Overflow:
error = FT_THROW( Invalid_Argument );
goto Exit;