bugThe FreeType Project - Bugs: bug #43539, FreeType 2.5.3 Mac font parsing...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #43539: FreeType 2.5.3 Mac font parsing heap-based buffer overflow due to integer signedness problems

Submitter:  Mateusz Jurczyk <j00ru>
Submitted:  Wed 05 Nov 2014 02:06:01 PM UTC
   
 
Severity:  3 - Normal Item Group:  Crash
Status:  Fixed Privacy:  Public
Assigned to:  mpsuzuki Open/Closed:  Closed
Planned Release:  2.5.4

Wed 26 Nov 2014 09:11:03 AM UTC, comment #5: 

Committed to GIT, in bug #43538 issue.

suzuki toshiya <mpsuzuki>
Group administrator
Tue 11 Nov 2014 04:21:29 AM UTC, comment #4: 

For further discussions, I decided to work this issue
in bug #43538 forum. Sorry for your inconvenience.

suzuki toshiya <mpsuzuki>
Group administrator
Tue 11 Nov 2014 12:51:10 AM UTC, comment #3: 

Here is a concatenated patch to fix #43538 + #43539.
Please check.

(file #32407)

suzuki toshiya <mpsuzuki>
Group administrator
Mon 10 Nov 2014 09:53:29 AM UTC, comment #2: 

Dear Mateusz,
Thank you for finding this issue, I could reproduce
the bug with gcc-4.8 + AddressSanitizer on Ubuntu/i386.
I will fix within this week!

suzuki toshiya <mpsuzuki>
Group administrator
Wed 05 Nov 2014 05:12:14 PM UTC, comment #1: 

Toshiya-san, please check this also.

Werner LEMBERG <wl>
Group administrator
Wed 05 Nov 2014 02:06:01 PM UTC, original submission:  

In the freetype/src/base/ftobjs.c file, we can find multiple auxiliary functions for handling uncommon or exotic font formats. One such function is "Mac_Read_POST_Resource", which heavily operates on user-supplied data:

1586:    FT_Long    len;
1587:    FT_Long    pfb_len, pfb_pos, pfb_lenpos;
1588:    FT_Long    rlen, temp;
...
1628:      if ( FT_READ_LONG( rlen ) )
1629:        goto Exit;
...
1676:      if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
1677:        goto Exit2;
1678:
1679:      error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
1680:      if ( error )
1681:        goto Exit2;
1682:      pfb_pos += rlen;

On 32-bit builds, the "rlen" variable is a fully controlled signed integer. While the if() statement in line 1676 attempts to perform bounds checking, all variables included in the expressions are of signed type, resulting in both comparisons being signed, too. If the value of "rlen" is negative, the check is bypassed, and the value is passed as the last parameter to FT_Stream_Read, which expects an unsigned count (ftstream.h):

367:  /* read bytes from a stream into a user-allocated buffer, returns an */
368:  /* error if not all bytes could be read.                             */
369:  FT_BASE( FT_Error )
370:  FT_Stream_Read( FT_Stream  stream,
371:                  FT_Byte*   buffer,
372:                  FT_ULong   count );

As a result, the function attempts to read an inadequately large number of bytes into a heap-based "pfb_data" buffer, thus resulting in memory corruption. This is illustrated by the attached example proof-of-concept sample (2.ttf), which triggers the following AddressSanitizer output:

=================================================================
==11824== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5d3eeeb at pc 0xf5fd9ad8 bp 0xffc84fa8 sp 0xffc84f9c
WRITE of size 1 at 0xf5d3eeeb thread T0
    #0 0xf5fd9ad7 in FT_Stream_ReadAt freetype2/src/base/ftstream.c:145
    #1 0xf5fd98a1 in FT_Stream_Read freetype2/src/base/ftstream.c:114
    #2 0xf5fc3c5e in Mac_Read_POST_Resource freetype2/src/base/ftobjs.c:1679
    #3 0xf5fc443f in IsMacResource freetype2/src/base/ftobjs.c:1811
    #4 0xf5fc4ad9 in IsMacBinary freetype2/src/base/ftobjs.c:1888
    #5 0xf5fc50a8 in load_mac_face freetype2/src/base/ftobjs.c:2003
    #6 0xf5fc59fe in FT_Open_Face freetype2/src/base/ftobjs.c:2165
    #7 0xf5fc24ff in FT_New_Face freetype2/src/base/ftobjs.c:1254
    #8 0x804b5a8 in get_face ft2demos-2.5.3/src/ftbench.c:705
    #9 0x804bc64 in main ft2demos-2.5.3/src/ftbench.c:924
0xf5d3eeeb is located 2862 bytes to the right of 236477-byte region [0xf5d04800,0xf5d3e3bd)
allocated by thread T0 here:
    #0 0xf61cf854 (/usr/lib32/libasan.so.0+0x16854)
    #1 0xf5fb6df7 in ft_alloc freetype2/builds/unix/ftsystem.c:102
    #2 0xf5fded74 in ft_mem_qalloc freetype2/src/base/ftutil.c:76
    #3 0xf5fdebde in ft_mem_alloc freetype2/src/base/ftutil.c:55
    #4 0xf5fc35de in Mac_Read_POST_Resource freetype2/src/base/ftobjs.c:1609
    #5 0xf5fc443f in IsMacResource freetype2/src/base/ftobjs.c:1811
    #6 0xf5fc4ad9 in IsMacBinary freetype2/src/base/ftobjs.c:1888
    #7 0xf5fc50a8 in load_mac_face freetype2/src/base/ftobjs.c:2003
    #8 0xf5fc59fe in FT_Open_Face freetype2/src/base/ftobjs.c:2165
    #9 0xf5fc24ff in FT_New_Face freetype2/src/base/ftobjs.c:1254
    #10 0x804b5a8 in get_face ft2demos-2.5.3/src/ftbench.c:705
    #11 0x804bc64 in main ft2demos-2.5.3/src/ftbench.c:924
    #12 0xf5e13a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
SUMMARY: AddressSanitizer: heap-buffer-overflow freetype2/src/base/ftstream.c:145 FT_Stream_ReadAt
Shadow bytes around the buggy address:
  0x3eba7d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3eba7dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]fa fa
  0x3eba7de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eba7e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==11824== ABORTING

Please note that this problem is very similar to https://savannah.nongnu.org/bugs/?30658, and is in fact caused by the fact that the fix introduced back then is not sufficient to prevent all types of attacks.

Mateusz Jurczyk <j00ru>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #32407:  mps20141111d.diff added by mpsuzuki (3KiB - text/x-patch)
file #32374:  2.ttf added by j00ru (237KiB - application/octet-stream)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mpsuzuki (Posted a comment)
  • -email is unavailable- added by wl (Posted a comment)
  • -email is unavailable- added by j00ru (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-08-22 wl PrivacyPrivate Public
    2014-11-26 mpsuzuki Open/ClosedOpen Closed
        Planned ReleaseNone 2.5.4
    2014-11-26 mpsuzuki StatusReady For Test Fixed
    2014-11-11 mpsuzuki Attached File- Added mps20141111d.diff, #32407
        StatusConfirmed Ready For Test
    2014-11-10 mpsuzuki StatusNone Confirmed
    2014-11-05 wl Assigned toNone mpsuzuki
    2014-11-05 j00ru Attached File- Added 2.ttf, #32374

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code