freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype][master] [colr] Avoid overflow in range checks


From: Werner Lemberg (@wl)
Subject: [Git][freetype/freetype][master] [colr] Avoid overflow in range checks
Date: Wed, 08 May 2024 03:02:31 +0000

Werner Lemberg pushed to branch master at FreeType / FreeType

Commits:

  • 5858fa16
    by Ben Wagner at 2024-05-08T05:01:16+02:00
    [colr] Avoid overflow in range checks
    
    In 32 bit builds `FT_ULong` is 32 bits and can silently overflow when a
    large number is read into one and then it is summed or multiplied with
    another number.  Checks for range overflow must be written so that they
    themselves do not overflow.  Also ensure that the table_size is always the
    first part of the range check and consistently use `<` or `<=`.
    
    * src/sfnt/ttcolr.c (tt_face_load_colr): Avoid overflow.
    (find_base_glyph_v1_record): Remove old work-around.
    
    Bug: https://issues.chromium.org/issues/41495455
    Bug: https://issues.chromium.org/issues/40945818
    

1 changed file:

Changes:

  • src/sfnt/ttcolr.c
    ... ... @@ -208,18 +208,19 @@
    208 208
         colr->num_base_glyphs = FT_NEXT_USHORT( p );
    
    209 209
         base_glyph_offset     = FT_NEXT_ULONG( p );
    
    210 210
     
    
    211
    -    if ( base_glyph_offset >= table_size )
    
    211
    +    if ( table_size <= base_glyph_offset )
    
    212 212
           goto InvalidTable;
    
    213
    -    if ( colr->num_base_glyphs * BASE_GLYPH_SIZE >
    
    214
    -           table_size - base_glyph_offset )
    
    213
    +    if ( ( table_size - base_glyph_offset ) / BASE_GLYPH_SIZE
    
    214
    +             < colr->num_base_glyphs )
    
    215 215
           goto InvalidTable;
    
    216 216
     
    
    217 217
         layer_offset     = FT_NEXT_ULONG( p );
    
    218 218
         colr->num_layers = FT_NEXT_USHORT( p );
    
    219 219
     
    
    220
    -    if ( layer_offset >= table_size )
    
    220
    +    if ( table_size <= layer_offset )
    
    221 221
           goto InvalidTable;
    
    222
    -    if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset )
    
    222
    +    if ( ( table_size - layer_offset ) / LAYER_SIZE
    
    223
    +             < colr->num_layers )
    
    223 224
           goto InvalidTable;
    
    224 225
     
    
    225 226
         if ( colr->version == 1 )
    
    ... ... @@ -229,14 +230,14 @@
    229 230
     
    
    230 231
           base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
    
    231 232
     
    
    232
    -      if ( base_glyphs_offset_v1 >= table_size - 4 )
    
    233
    +      if ( table_size - 4 <= base_glyphs_offset_v1 )
    
    233 234
             goto InvalidTable;
    
    234 235
     
    
    235 236
           p1                 = (FT_Byte*)( table + base_glyphs_offset_v1 );
    
    236 237
           num_base_glyphs_v1 = FT_PEEK_ULONG( p1 );
    
    237 238
     
    
    238
    -      if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE >
    
    239
    -             table_size - base_glyphs_offset_v1 )
    
    239
    +      if ( ( table_size - base_glyphs_offset_v1 ) / BASE_GLYPH_PAINT_RECORD_SIZE
    
    240
    +               < num_base_glyphs_v1 )
    
    240 241
             goto InvalidTable;
    
    241 242
     
    
    242 243
           colr->num_base_glyphs_v1 = num_base_glyphs_v1;
    
    ... ... @@ -244,19 +245,19 @@
    244 245
     
    
    245 246
           layer_offset_v1 = FT_NEXT_ULONG( p );
    
    246 247
     
    
    247
    -      if ( layer_offset_v1 >= table_size )
    
    248
    +      if ( table_size <= layer_offset_v1 )
    
    248 249
             goto InvalidTable;
    
    249 250
     
    
    250 251
           if ( layer_offset_v1 )
    
    251 252
           {
    
    252
    -        if ( layer_offset_v1 >= table_size - 4 )
    
    253
    +        if ( table_size - 4 <= layer_offset_v1 )
    
    253 254
               goto InvalidTable;
    
    254 255
     
    
    255 256
             p1            = (FT_Byte*)( table + layer_offset_v1 );
    
    256 257
             num_layers_v1 = FT_PEEK_ULONG( p1 );
    
    257 258
     
    
    258
    -        if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE >
    
    259
    -               table_size - layer_offset_v1 )
    
    259
    +        if ( ( table_size - layer_offset_v1 ) / LAYER_V1_LIST_PAINT_OFFSET_SIZE
    
    260
    +                < num_layers_v1 )
    
    260 261
               goto InvalidTable;
    
    261 262
     
    
    262 263
             colr->num_layers_v1 = num_layers_v1;
    
    ... ... @@ -279,7 +280,7 @@
    279 280
     
    
    280 281
           clip_list_offset = FT_NEXT_ULONG( p );
    
    281 282
     
    
    282
    -      if ( clip_list_offset >= table_size )
    
    283
    +      if ( table_size <= clip_list_offset )
    
    283 284
             goto InvalidTable;
    
    284 285
     
    
    285 286
           if ( clip_list_offset )
    
    ... ... @@ -311,7 +312,7 @@
    311 312
               goto InvalidTable;
    
    312 313
     
    
    313 314
             var_store_offset = FT_NEXT_ULONG( p );
    
    314
    -        if ( var_store_offset >= table_size )
    
    315
    +        if ( table_size <= var_store_offset )
    
    315 316
               goto InvalidTable;
    
    316 317
     
    
    317 318
             if ( var_store_offset )
    
    ... ... @@ -1270,7 +1271,6 @@
    1270 1271
       static FT_Bool
    
    1271 1272
       find_base_glyph_v1_record( FT_Byte *           base_glyph_begin,
    
    1272 1273
                                  FT_UInt             num_base_glyph,
    
    1273
    -                             FT_Byte *           end_colr,
    
    1274 1274
                                  FT_UInt             glyph_id,
    
    1275 1275
                                  BaseGlyphV1Record  *record )
    
    1276 1276
       {
    
    ... ... @@ -1290,14 +1290,6 @@
    1290 1290
            */
    
    1291 1291
           FT_Byte  *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE;
    
    1292 1292
     
    
    1293
    -
    
    1294
    -      /* We need to be able to read 2 bytes (FT_NEXT_USHORT) for the glyph */
    
    1295
    -      /* ID, then 4 bytes (FT_NEXT_ULONG) for the paint offset.  If that's */
    
    1296
    -      /* not available before the end of the table, something's wrong with */
    
    1297
    -      /* the font and we can't find a COLRv1 glyph.                        */
    
    1298
    -      if ( p > end_colr - 2 - 4 )
    
    1299
    -        return 0;
    
    1300
    -
    
    1301 1293
           gid = FT_NEXT_USHORT( p );
    
    1302 1294
     
    
    1303 1295
           if ( gid < glyph_id )
    
    ... ... @@ -1338,7 +1330,6 @@
    1338 1330
     
    
    1339 1331
         if ( !find_base_glyph_v1_record( colr->base_glyphs_v1,
    
    1340 1332
                                          colr->num_base_glyphs_v1,
    
    1341
    -                                     (FT_Byte*)colr->table + colr->table_size,
    
    1342 1333
                                          base_glyph,
    
    1343 1334
                                          &base_glyph_v1_record ) )
    
    1344 1335
           return 0;
    


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]