Exploit-DB #46723
Description: Oracle Java Runtime Environment - Heap Corruption During TTF font Rendering in GlyphIterator::setCurrGlyphID
Type: dos
Platform: multiple
Date: 2019-04-17
Author: Google Security Research

Exploit:
A heap corruption was observed in Oracle Java Runtime Environment version 8u202 (latest at the time of this writing) while fuzz-testing the processing of TrueType fonts. It manifests itself in the form of the following (or similar) crash:

--- cut ---
  $ bin/java -cp . DisplaySfntFont test.ttf
  Iteration (0,0)
  #
  # A fatal error has been detected by the Java Runtime Environment:
  #
  #  SIGSEGV (0xb) at pc=0x00007f7285b39824, pid=234398, tid=0x00007f[PII_REDACTED]
  #
  # JRE version: Java(TM) SE Runtime Environment (8.0_202-b08) (build 1.8.0_202-b08)
  # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.202-b08 mixed mode linux-amd64 compressed oops)
  # Problematic frame:
  # C  [libc.so.6+0x77824]# [ timer expired, abort... ]
  Aborted
--- cut ---

The crash reproduces on both Windows and Linux platforms. On Linux, it can be also triggered with the MALLOC_CHECK_=3 environment variable:

--- cut ---
  $ MALLOC_CHECK_=3 bin/java -cp . DisplaySfntFont test.ttf
  Iteration (0,0)
  *** Error in `bin/java': free(): invalid pointer: 0x[PII_REDACTED]876320 ***
  ======= Backtrace: =========
  /lib/x86_64-linux-gnu/libc.so.6(+0x70bcb)[0x7f84185edbcb]
  /lib/x86_64-linux-gnu/libc.so.6(+0x76f96)[0x7f84185f3f96]
  jre/8u202/lib/amd64/libfontmanager.so(+0x1d2b2)[0x7f83ddc672b2]
  jre/8u202/lib/amd64/libfontmanager.so(+0x27ff4)[0x7f83ddc71ff4]
  jre/8u202/lib/amd64/libfontmanager.so(+0x866f)[0x7f83ddc5266f]
  jre/8u202/lib/amd64/libfontmanager.so(Java_sun_font_SunLayoutEngine_nativeLayout+0x230)[0x7f83ddc78990]
  [0x7f84076306c7]
  ======= Memory map: ========
  [PII_REDACTED] r-xp 00000000 fe:01 20840680                           jre/8u202/bin/java
  [PII_REDACTED] r--p 00000000 fe:01 20840680                           jre/8u202/bin/java
  [PII_REDACTED] rw-p 00001000 fe:01 20840680                           jre/8u202/bin/java
  023ba000-028d9000 rw-p 00000000 00:00 0                                  [heap]
  3d1a00000-3fba00000 rw-p 00000000 00:00 0
  3fba00[PII_REDACTED]00 ---p 00000000 00:00 0
  670[PII_REDACTED]00000 rw-p 00000000 00:00 0
  685900000-7c0000000 ---p 00000000 00:00 0
  7c0000000-7c00c0000 rw-p 00000000 00:00 0
  7c00c0[PII_REDACTED]00 ---p 00000000 00:00 0
  [...]
--- cut ---

... under Valgrind:

--- cut ---
  $ valgrind bin/java -cp . DisplaySfntFont test.ttf
  [...]
  ==245623== Invalid write of size 2
  ==245623==    at 0x40BF2750: GlyphIterator::setCurrGlyphID(unsigned short) (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C0C089: SingleSubstitutionFormat1Subtable::process(LEReferenceTo<SingleSubstitutionFormat1Subtable> const&, GlyphIterator*, LEErrorCode&, LEGlyphFilter const*) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C0C4A4: SingleSubstitutionSubtable::process(LEReferenceTo<SingleSubstitutionSubtable> const&, GlyphIterator*, LEErrorCode&, LEGlyphFilter const*) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BF47E5: GlyphSubstitutionLookupProcessor::applySubtable(LEReferenceTo<LookupSubtable> const&, unsigned short, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const [clone .part.11] (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C01DCE: LookupProcessor::applyLookupTable(LEReferenceTo<LookupTable> const&, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C02FBA: LookupProcessor::applySingleLookup(unsigned short, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BEBC9C: ContextualSubstitutionBase::applySubstitutionLookups(LookupProcessor const*, LEReferenceToArrayOf<SubstitutionLookupRecord> const&, unsigned short, GlyphIterator*, LEFontInstance const*, int, LEErrorCode&) (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BEE766: ChainingContextualSubstitutionFormat3Subtable::process(LETableReference const&, LookupProcessor const*, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BEE8E3: ChainingContextualSubstitutionSubtable::process(LEReferenceTo<ChainingContextualSubstitutionSubtable> const&, LookupProcessor const*, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BF475B: GlyphSubstitutionLookupProcessor::applySubtable(LEReferenceTo<LookupSubtable> const&, unsigned short, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const [clone .part.11] (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C01DCE: LookupProcessor::applyLookupTable(LEReferenceTo<LookupTable> const&, GlyphIterator*, LEFontInstance const*, LEErrorCode&) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C02EAB: LookupProcessor::process(LEGlyphStorage&, GlyphPositionAdjustments*, char, LEReferenceTo<GlyphDefinitionTableHeader> const&, LEFontInstance const*, LEErrorCode&) const (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==  Address 0x3f68a55c is 4 bytes before a block of size 104 alloc'd
  ==245623==    at 0x4C2BBEF: malloc (vg_replace_malloc.c:299)
  ==245623==    by 0x40BFD4CF: LEGlyphStorage::allocateGlyphArray(int, char, LEErrorCode&) (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BE875A: ArabicOpenTypeLayoutEngine::characterProcessing(unsigned short const*, int, int, int, char, unsigned short*&, LEGlyphStorage&, LEErrorCode&) (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C0815F: OpenTypeLayoutEngine::computeGlyphs(unsigned short const*, int, int, int, char, LEGlyphStorage&, LEErrorCode&) (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40BFE55D: LayoutEngine::layoutChars(unsigned short const*, int, int, int, char, float, float, LEErrorCode&) (in jre/8u202/lib/amd64/libfontmanager.so)
  ==245623==    by 0x40C0E91F: Java_sun_font