Microsoft Windows - Uniscribe Font Processing Out-of-Bounds Read in usp10!otlChainRuleSetTable::rule (MS17-011)

EDB-ID:

41646




Platform:

Windows

Date:

2017-03-20


Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1019

We have encountered a crash in the Windows Uniscribe user-mode library, in the usp10!otlChainRuleSetTable::rule function, while trying to display text using a corrupted TTF font file:

---
(4464.11b4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0933d8bf ebx=00000000 ecx=09340ffc edx=00001b9f esi=0026ecac edi=00000009
eip=752378f3 esp=0026ec24 ebp=0026ec2c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
USP10!ScriptPositionSingleGlyph+0x28533:
752378f3 668b4c5002      mov     cx,word ptr [eax+edx*2+2] ds:002b:09340fff=????

0:000> kb
ChildEBP RetAddr  Args to Child              
0026ec2c 752382f3 0026ecac 00001b9f 09340ffc USP10!otlChainRuleSetTable::rule+0x13
0026eccc 75231471 42555347 0026f078 0133d7d2 USP10!otlChainingLookup::apply+0x7d3
0026ed48 752335e1 000000e4 0026f078 0026f09c USP10!ApplyLookup+0x261
0026ef4c 7522f29f 42555347 0026f0b4 0026f078 USP10!ApplyFeatures+0x481
0026ef98 7522f710 00000000 09342ffa 09342f40 USP10!SubstituteOtlGlyphs+0x1bf
0026efd4 752213c0 0026f050 0026f088 0026f0b4 USP10!SubstituteOtlChars+0x220
0026f250 7521548a 0026f35c 0026f388 0026f370 USP10!HebrewEngineGetGlyphs+0x690
0026f310 7521253f 0026f35c 0026f388 0026f370 USP10!ShapingGetGlyphs+0x36a
0026f3fc 751e5c6f 2d011da2 09316124 09316318 USP10!ShlShape+0x2ef
0026f440 751f167a 2d011da2 09316124 09316318 USP10!ScriptShape+0x15f
0026f4a0 751f2b14 00000000 00000000 0026f520 USP10!RenderItemNoFallback+0xfa
0026f4cc 751f2da2 00000000 00000000 0026f520 USP10!RenderItemWithFallback+0x104
0026f4f0 751f4339 00000000 0026f520 09316124 USP10!RenderItem+0x22
0026f534 751e7a04 000004a0 00000400 2d011da2 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0026f54c 76ca5465 2d011da2 09316040 0000000a USP10!ScriptStringAnalyse+0x284
0026f598 76ca5172 2d011da2 0026fa1c 0000000a LPK!LpkStringAnalyse+0xe5
0026f694 76ca1410 2d011da2 00000000 00000000 LPK!LpkCharsetDraw+0x332
0026f6c8 763c18b0 2d011da2 00000000 00000000 LPK!LpkDrawTextEx+0x40
0026f708 763c22bf 2d011da2 00000048 00000000 USER32!DT_DrawStr+0x13c
0026f754 763c21f2 2d011da2 0026fa1c 0026fa30 USER32!DT_GetLineBreak+0x78
0026f800 763c14d4 2d011da2 00000000 0000000a USER32!DrawTextExWorker+0x255
0026f824 763c2475 2d011da2 0026fa1c ffffffff USER32!DrawTextExW+0x1e
[...]
---

The crash is caused by a single-byte change in a legitimate font file: at offset 0x845A, byte 0x00 is changed to 0xFF. The data region corresponds to the "GSUB" sfnt table. The change causes the otlChainRuleTable::backtrackGlyphCount() function to return an overly large 16-bit integer of 0xED00, which is then used as the number of iterations in a subsequent loop in the otlChainingLookup::apply() function, without prior validation. Increasing (out-of-bounds) indexes are then passed to otlChainRuleSetTable::rule() in the 2nd parameter, and used to address an array of 16-bit indexes. This is where the crash takes place, as the large index eventually starts pointing into the boundary of the last mapped heap memory page.

The 16-bit value being read from outside the allocated buffer is later used as yet another index, used to address some an array in the otlChainRuleTable::otlChainRuleTable() routine. While the function only appears to read from the newly formed pointer at first glance, we are not ruling out the possibility of memory corruption. In a read-only scenario, the issue could be potentially used to disclose sensitive data from the process heap.

The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled, but it is also possible to observe a crash in a default system configuration. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays all of the font's glyphs at various point sizes.

Attached is an archive with the original and modified TTF files.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41646.zip