New issue
Advanced search Search tips
Starred by 2 users
Status: Fixed
Owner:
Closed: Nov 2014
Cc:



Sign in to add a comment
FreeType 2.5.3 sbix PNG handling heap-based buffer overflow due to integer overflow
Project Member Reported by mjurczyk@google.com, Nov 13 2014 Back to list
FreeType 2.5.3 supports embedded bitmaps in SFNT-based fonts, in one of the three standard graphics formats (PNG), while JPEG and TIFF are not yet supported. Such bitmaps can be found in the Apple-defined "sbix" tables (see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html), which in the PNG case is internally handled in FreeType by the "Load_SBit_Png" function implemented in freetype/src/sfnt/pngshim.c.

In addition to bitmap data itself, additional glyph information such as width, height, bit depth etc. is obtained from corresponding PNG headers (specifically, IHDR) and used to initialize internal FT structures:

194:    png_uint_32  imgWidth, imgHeight;
195:
196:    int         bitdepth, color_type, interlace;
...
247:    png_get_IHDR( png, info,
248:                  &imgWidth, &imgHeight,
249:                  &bitdepth, &color_type, &interlace,
250:                  NULL, NULL );
...
258:    if ( populate_map_and_metrics )
259:    {
260:      FT_Long  size;
261:
262:
263:      metrics->width  = (FT_Int)imgWidth;
264:      metrics->height = (FT_Int)imgHeight;
265:
266:      map->width      = metrics->width;
267:      map->rows       = metrics->height;
268:      map->pixel_mode = FT_PIXEL_MODE_BGRA;
269:      map->pitch      = map->width * 4;
270:      map->num_grays  = 256;

More importantly, these sizes are further used with no bounds checks, in order to calculate the overall buffer size for the PNG data:

272:      size = map->rows * map->pitch;
273:
274:      error = ft_glyphslot_alloc_bitmap( slot, size );

The bitmap pixels are subsequently loaded into the buffer:

349:    for ( i = 0; i < (FT_Int)imgHeight; i++ )
350:      rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4;
351:
352:    png_read_image( png, rows );

Now, since PNG supports very large images (the width and height fields in IHDR are 32-bit wide) and the "Load_SBit_Png" function blindly trusts the loaded dimensions, it is possible to overflow the "map->rows * map->pitch" expression, thus under-allocating the resulting buffer and later causing a heap-based buffer overflow.

Attached please find a font file (poc.ttf) with a valid embedded PNG file of width=65535 and height=16385, which causes "map->pitch" to become 262140, and "size" to become (uint32)(262140 * 16385) = (uint32)4295163900 = 196604. Since over 4GB of data is attempted to be loaded into a very small buffer, the sample triggers a SIGSEGV signal, or the following AddressSanitizer report.

In order to reproduce, run: $ ftview 150 /path/to/poc.ttf

=================================================================
==21730== ERROR: AddressSanitizer: unknown-crash on address 0xf57cf800 at pc 0xf6121ce0 bp 0xffba2718 sp 0xffba22f8
WRITE of size 262140 at 0xf57cf800 thread T0
    #0 0xf6121cdf (/usr/lib32/libasan.so.0+0xdcdf)
    #1 0xf5b60ea1 (/lib/i386-linux-gnu/libpng12.so.0+0x9ea1)
    #2 0xf5b681f7 (/lib/i386-linux-gnu/libpng12.so.0+0x111f7)
    #3 0xf5b68669 (/lib/i386-linux-gnu/libpng12.so.0+0x11669)
    #4 0xf60460a3 in Load_SBit_Png freetype2/src/sfnt/pngshim.c:352
    #5 0xf604c768 in tt_face_load_sbix_image freetype2/src/sfnt/ttsbit.c:1320
    #6 0xf604cb8e in tt_face_load_sbit_image freetype2/src/sfnt/ttsbit.c:1395
    #7 0xf5f621b6 in load_sbit_image freetype2/src/truetype/ttgload.c:2036
    #8 0xf5f633a6 in TT_Load_Glyph freetype2/src/truetype/ttgload.c:2360
    #9 0xf5f539f9 in tt_glyph_load freetype2/src/truetype/ttdriver.c:404
    #10 0xf5f188f3 in FT_Load_Glyph freetype2/src/base/ftobjs.c:726
    #11 0xf60a315e in ftc_basic_family_load_glyph freetype2/src/cache/ftcbasic.c:173
    #12 0xf60a0937 in FTC_INode_New freetype2/src/cache/ftcimage.c:79
    #13 0xf60a09eb in ftc_inode_new freetype2/src/cache/ftcimage.c:102
    #14 0xf609e4ff in FTC_Cache_NewNode freetype2/src/cache/ftccache.c:461
    #15 0xf60a5115 in FTC_ImageCache_LookupScaler freetype2/src/cache/ftcbasic.c:389
    #16 0x8059ca0 in FTDemo_Index_To_Bitmap ft2demos-2.5.3/src/ftcommon.c:859
    #17 0x8059e42 in FTDemo_Draw_Index ft2demos-2.5.3/src/ftcommon.c:892
    #18 0x804bcce in Render_All ft2demos-2.5.3/src/ftview.c:493
    #19 0x80540c4 in main ft2demos-2.5.3/src/ftview.c:1974
0xf57ff7fc is located 0 bytes to the right of 196604-byte region [0xf57cf800,0xf57ff7fc)
allocated by thread T0 here:
    #0 0xf612a854 (/usr/lib32/libasan.so.0+0x16854)
    #1 0xf5f0f387 in ft_alloc freetype2/builds/unix/ftsystem.c:102
    #2 0xf5f37304 in ft_mem_qalloc freetype2/src/base/ftutil.c:76
    #3 0xf5f3716e in ft_mem_alloc freetype2/src/base/ftutil.c:55
    #4 0xf5f1637e in ft_glyphslot_alloc_bitmap freetype2/src/base/ftobjs.c:332
    #5 0xf6045d27 in Load_SBit_Png freetype2/src/sfnt/pngshim.c:274
    #6 0xf604c768 in tt_face_load_sbix_image freetype2/src/sfnt/ttsbit.c:1320
    #7 0xf604cb8e in tt_face_load_sbit_image freetype2/src/sfnt/ttsbit.c:1395
    #8 0xf5f621b6 in load_sbit_image freetype2/src/truetype/ttgload.c:2036
    #9 0xf5f633a6 in TT_Load_Glyph freetype2/src/truetype/ttgload.c:2360
    #10 0xf5f539f9 in tt_glyph_load freetype2/src/truetype/ttdriver.c:404
    #11 0xf5f188f3 in FT_Load_Glyph freetype2/src/base/ftobjs.c:726
    #12 0xf60a315e in ftc_basic_family_load_glyph freetype2/src/cache/ftcbasic.c:173
    #13 0xf60a0937 in FTC_INode_New freetype2/src/cache/ftcimage.c:79
    #14 0xf60a09eb in ftc_inode_new freetype2/src/cache/ftcimage.c:102
    #15 0xf609e4ff in FTC_Cache_NewNode freetype2/src/cache/ftccache.c:461
    #16 0xf60a5115 in FTC_ImageCache_LookupScaler freetype2/src/cache/ftcbasic.c:389
    #17 0x8059ca0 in FTDemo_Index_To_Bitmap ft2demos-2.5.3/src/ftcommon.c:859
    #18 0x8059e42 in FTDemo_Draw_Index ft2demos-2.5.3/src/ftcommon.c:892
    #19 0x804bcce in Render_All ft2demos-2.5.3/src/ftview.c:493
    #20 0x80540c4 in main ft2demos-2.5.3/src/ftview.c:1974
SUMMARY: AddressSanitizer: unknown-crash ??:0 ??
Shadow bytes around the buggy address:
  0x3eaf9eb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eaf9ec0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eaf9ed0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eaf9ee0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3eaf9ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3eaf9f00:[00]00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3eaf9f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3eaf9f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3eaf9f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3eaf9f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3eaf9f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==21730== ABORTING
 
poc.ttf
1.0 MB Download
Project Member Comment 1 by mjurczyk@google.com, Nov 13 2014
Reported in https://savannah.nongnu.org/bugs/?43597.
Comment 3 by cevans@google.com, Jan 26 2015
Labels: -Restrict-View-Commit
All fixed by upstream:

FreeType 2.5.5

2014-12-30
FreeType 2.5.5 has been released. This is a minor bug fix release: All users of PCF fonts should update, since version 2.5.4 introduced a bug that prevented reading of such font files if not compressed.

FreeType 2.5.4

2014-12-06
FreeType 2.5.4 has been released. All users should upgrade due to another fix for vulnerability CVE-2014-2240 in the CFF driver. The library also contains a new round of patches for better protection against malformed fonts.

The main new feature, which is also one of the targets mentioned in the pledgie roadmap below, is auto-hinting support for Devanagari and Telugu, two widely used Indic scripts. A more detailed description of the remaining changes and fixes can be found here.


Project Member Comment 4 by mjurczyk@google.com, Feb 25 2015
Labels: CVE-2014-9665
Project Member Comment 5 by mjurczyk@google.com, Apr 20 2015
Labels: Fixed-2014-Nov-21
Sign in to add a comment