Microsoft Windows - Uniscribe Font Processing Heap Memory Corruption Around 'USP10!BuildFSM' (MS17-011)








We have encountered a number of crashes in the Windows Uniscribe user-mode library, while trying to display text using a corrupted font file. While crashes in this specific family take various shapes and forms, they all occur in functions directly or indirectly called by USP10!BuildFSM. An example crash excerpt is shown below:

(5020.4074): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=000000cc ebx=0964b270 ecx=0964c6aa edx=0038f409 esi=00000782 edi=0963d7d0
eip=751f968d esp=0038f3bc ebp=0038f468 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010216
751f968d 668944b302      mov     word ptr [ebx+esi*4+2],ax ds:002b:0964d07a=????
0:000> kb
ChildEBP RetAddr  Args to Child              
0038f468 751f7a33 00000048 09649700 0000001a USP10!BuildDynamicStatesStaticInputs+0x45d
0038f6a0 751f7076 095d3d88 095e1fa8 0038f6cc USP10!BuildFSM+0x193
0038f6b0 751fc5f4 c10125b4 095d3d88 095c6124 USP10!LoadArabicShapeTables+0x106
0038f6cc 751ea5a0 c10125b4 0963d7d0 0000001a USP10!ArabicLoadTbl+0xd4
0038f6f0 751ea692 095c6124 c10125b4 0000001a USP10!UpdateCache+0xb0
0038f704 751f152d c10125b4 095c6000 751f15db USP10!ScriptCheckCache+0x62
0038f710 751f15db 00000001 00000001 095c62e8 USP10!GetShapeFunction+0xd
0038f748 751f2b14 00000001 00000000 0038f7c8 USP10!RenderItemNoFallback+0x5b
0038f774 751f2da2 00000001 00000000 0038f7c8 USP10!RenderItemWithFallback+0x104
0038f798 751f4339 00000000 0038f7c8 095c6124 USP10!RenderItem+0x22
0038f7dc 751e7a04 000004a0 00000400 c10125b4 USP10!ScriptStringAnalyzeGlyphs+0x1e9
0038f7f4 76ca5465 c10125b4 095c6040 0000000a USP10!ScriptStringAnalyse+0x284
0038f840 76ca5172 c10125b4 0038fc28 0000000a LPK!LpkStringAnalyse+0xe5
0038f93c 76ca1410 c10125b4 00000000 00000000 LPK!LpkCharsetDraw+0x332
0038f970 763c18b0 c10125b4 00000000 00000000 LPK!LpkDrawTextEx+0x40
0038f9b0 763c22bf c10125b4 00000040 00000000 USER32!DT_DrawStr+0x13c
0038f9fc 763c21f2 c10125b4 0038fc28 0038fc3c USER32!DT_GetLineBreak+0x78
0038faa8 763c14d4 c10125b4 00000000 0000000a USER32!DrawTextExWorker+0x255
0038facc 763c2475 c10125b4 0038fc28 ffffffff USER32!DrawTextExW+0x1e
0038fb00 01196a5c c10125b4 0038fc28 ffffffff USER32!DrawTextW+0x4d
0:000> !heap -p -a ebx
    address 0964b270 found in
    _DPH_HEAP_ROOT @ 95c1000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                 95c2ed4:          964b270             1d8c -          964b000             3000
    5dbb8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
    77580f3e ntdll!RtlDebugAllocateHeap+0x00000030
    7753ab47 ntdll!RtlpAllocateHeap+0x000000c4
    774e3431 ntdll!RtlAllocateHeap+0x0000023a
    5fcca792 vrfcore!VfCoreRtlAllocateHeap+0x00000016
    751f6644 USP10!UspAllocCache+0x00000054
    751f7975 USP10!BuildFSM+0x000000d5
    751f7076 USP10!LoadArabicShapeTables+0x00000106
    751fc5f4 USP10!ArabicLoadTbl+0x000000d4
    751ea5a0 USP10!UpdateCache+0x000000b0
    751ea692 USP10!ScriptCheckCache+0x00000062
    751f152d USP10!GetShapeFunction+0x0000000d
    751f2b14 USP10!RenderItemWithFallback+0x00000104
    751f2da2 USP10!RenderItem+0x00000022
    751f4339 USP10!ScriptStringAnalyzeGlyphs+0x000001e9
    751e7a04 USP10!ScriptStringAnalyse+0x00000284
    76ca5465 LPK!LpkStringAnalyse+0x000000e5
    76ca5172 LPK!LpkCharsetDraw+0x00000332
    76ca1410 LPK!LpkDrawTextEx+0x00000040
    763c18b0 USER32!DT_DrawStr+0x0000013c
    763c22bf USER32!DT_GetLineBreak+0x00000078
    763c21f2 USER32!DrawTextExWorker+0x00000255
    763c14d4 USER32!DrawTextExW+0x0000001e
    763c2475 USER32!DrawTextW+0x0000004d

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 2 crashing samples.

Proof of Concept: