ganado / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

FreeType 2.5.3 CFF hintmap building stack-based arbitrary out-of-bounds write #190

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
There is a vulnerability in the CFF CharString interpreter used by FreeType 
2.5.3 (the Adobe CFF rasterizer contributed to the project in June 2013, see 
[1]), which makes it possible for a specially crafted OpenType file to perform 
arbitrary out-of-bounds writes on the interpreter function stack. This in turn 
makes it possible to create a font file which takes over the program control 
flow and reliably executes arbitrary code included in the input file.

Interestingly, this is not a new bug, but a variant of CVE-2014-2241 which I 
reported on February 24th, 2014 here: https://savannah.nongnu.org/bugs/?41697. 
As it turns out, the fix submitted in commit 
0eae6eb0645264c98812f0095e0f5df4541830e6 [2] is not sufficient to entirely 
close the loophole. Attached are several testcases which reach the vulnerable 
"cf2_hintmap_build" function through a different code path 
("cf2_glyphpath_moveTo" instead of directly from "cf2_interpT2CharString"). 
This makes it possible to bypass the original fix, because the if() statement 
in cf2hints.c:778 never executes, thus leading to the processing a 
"hStemHintArray" object longer than the maximum 96 allowed entries.

The issue has been reproduced with the current version of freetype2 from master 
git branch, with a 64-bit build of the ftbench utility compiled with 
AddressSanitizer:

$ ftbench <file>

I believe the immediate reason why the problem still exists today is that the 
following TODO comment in cf2hints.c:797 has still not been resolved, while in 
my opinion it should have been:

796:    /* use the hStem hints only, which are first in the mask */
797:    /* TODO: compare this to cffhintmaskGetBitCount */
798:    bitCount = cf2_arrstack_size( hStemHintArray );

If it was, the fix would be effective and couldn't be bypassed to cause a 
stack-based non-continuous buffer overflow anymore.

Below is an example AddressSanitizer report illustrating the problem:

=================================================================
==15055==ERROR: AddressSanitizer: stack-buffer-overflow on address 
0x7fff2dc05b30 at pc 0x71134e bp 0x7fff2dc055b0 sp 0x7fff2dc055a8
READ of size 1 at 0x7fff2dc05b30 thread T0
    #0 0x71134d in cf2_hintmap_build freetype2/src/cff/cf2hints.c:822
    #1 0x7048e1 in cf2_glyphpath_moveTo freetype2/src/cff/cf2hints.c:1606
    #2 0x6f5259 in cf2_interpT2CharString freetype2/src/cff/cf2intrp.c:1243
    #3 0x6e8570 in cf2_getGlyphOutline freetype2/src/cff/cf2font.c:469
    #4 0x6e4c5e in cf2_decoder_parse_charstrings freetype2/src/cff/cf2ft.c:367
    #5 0x6da446 in cff_slot_load freetype2/src/cff/cffgload.c:2840
    #6 0x69dbcc in cff_glyph_load freetype2/src/cff/cffdrivr.c:185
    #7 0x4a427e in FT_Load_Glyph freetype2/src/base/ftobjs.c:726
    #8 0x491d69 in test_load ft2demos-2.5.3/src/ftbench.c:249
    #9 0x492b51 in benchmark ft2demos-2.5.3/src/ftbench.c:216
    #10 0x48e962 in main ft2demos-2.5.3/src/ftbench.c:1020

Address 0x7fff2dc05b30 is located in stack of thread T0 at offset 304 in frame
    #0 0x7100cf in cf2_hintmap_build freetype2/src/cff/cf2hints.c:754

  This frame has 20 object(s):
    [32, 40) ''
    [64, 72) ''
    [96, 104) ''
    [128, 136) ''
    [160, 164) ''
    [176, 177) ''
    [192, 200) 'maskPtr'
    [224, 232) 'font'
    [256, 304) 'tempHintMask' <== Memory access at offset 304 overflows this variable
    [336, 344) 'bitCount'
    [368, 376) 'i'
    [400, 401) 'maskByte'
    [416, 448) 'dummy'
    [480, 512) 'bottomHintEdge'
    [544, 576) 'topHintEdge'
    [608, 640) 'edge'
    [672, 704) 'invalid'
    [736, 768) 'bottomHintEdge1'
    [800, 832) 'topHintEdge2'
    [864, 872) 'stemhint'
HINT: this may be a false positive if your program uses some custom stack 
unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow 
freetype2/src/cff/cf2hints.c:822 cf2_hintmap_build
Shadow bytes around the buggy address:
  0x100065b78b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100065b78b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100065b78b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100065b78b40: f1 f1 f1 f1 00 f2 f2 f2 00 f2 f2 f2 00 f2 f2 f2
  0x100065b78b50: 00 f2 f2 f2 04 f2 01 f2 00 f2 f2 f2 00 f2 f2 f2
=>0x100065b78b60: 00 00 00 00 00 00[f2]f2 f2 f2 00 f2 f2 f2 00 f2
  0x100065b78b70: f2 f2 01 f2 00 00 00 00 f2 f2 f2 f2 00 00 00 00
  0x100065b78b80: f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00 00 00
  0x100065b78b90: f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00 00 00
  0x100065b78ba0: f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 f3 f3 f3
  0x100065b78bb0: 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 right 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
  Contiguous container OOB:fc
  ASan internal:           fe
==15055==ABORTING

References:
[1] 
http://blog.typekit.com/2013/06/19/adobe-cff-font-rasterizer-accepted-by-freetyp
e/
[2] 
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=0eae6eb064526
4c98812f0095e0f5df4541830e6

Original issue reported on code.google.com by mjurc...@google.com on 21 Nov 2014 at 12:41

Attachments:

GoogleCodeExporter commented 9 years ago
Small correction: this is a variant of CVE-2014-2240.

Original comment by mjurc...@google.com on 21 Nov 2014 at 12:43

GoogleCodeExporter commented 9 years ago
Reported in https://savannah.nongnu.org/bugs/?43661.

Original comment by mjurc...@google.com on 21 Nov 2014 at 12:46

GoogleCodeExporter commented 9 years ago
Fixed in 
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=2cdc4562f8732
37f1c77d43540537c7a721d3fd8.

Original comment by mjurc...@google.com on 4 Dec 2014 at 3:10

GoogleCodeExporter commented 9 years ago
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.

Original comment by cev...@google.com on 26 Jan 2015 at 5:27

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 25 Feb 2015 at 1:56