Microsoft Windows - Uniscribe Font Processing Buffer Overflow in 'USP10!FillAlternatesList' (MS17-011)








We have encountered a crash in the Windows Uniscribe user-mode library, in the USP10!FillAlternatesList function, while trying to request a list of alternate glyphs for a specific glyph in a corrupted font file:

(4bfc.c60): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000000d ebx=0021006f ecx=00000010 edx=00000018 esi=07b4bfe8 edi=0021f620
eip=75232fe1 esp=0021f550 ebp=0021f5b8 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
75232fe1 66891c32        mov     word ptr [edx+esi],bx    ds:002b:07b4c000=????
0:000> kb
ChildEBP RetAddr  Args to Child              
0021f5b8 7522eb56 09312db6 00000000 00000003 USP10!FillAlternatesList+0x2d1
0021f5ec 75208b38 0021f640 0021f614 746c6161 USP10!GetOtlGlyphAlternates+0x86
0021f770 7520f214 0021f9d8 6e74616c 746c6664 USP10!OtlGetAlternateGlyphList+0x108
0021f7a0 00dc4557 30011a14 00000001 00000000 USP10!ScriptGetFontAlternateGlyphs+0xb4

In our test harness, we set the cMaxAlternates parameter of the ScriptGetFontAlternateGlyphs function to 10, indicating that this is the maximum number of values which can be written to the output pAlternateGlyphs array. However, the API function does not seem to respect the argument and attempts to write more data into the buffer -- in this case, 29 WORDs. The vulnerability can also be confirmed by looking at the output value of pcAlternates, which should never exceed 10 in this case, but is indeed set to 29. As a result, the bug may lead to corruption of various memory areas, including stack, heap, and static memory, depending on the type of pointer passed to the function by its caller.

The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled and the output buffer allocated from the heap. In order to reproduce the problem with the provided samples, it is necessary to use a custom program which calls the vulnerable API function.

Attached is a proof of concept malformed font file which triggers the crash.

Proof of Concept: