Microsoft GDI+ - 'gdiplus!GetRECTSForPlayback' Out-of-Bounds Read (MS17-013)








We have encountered a crash in the Windows GDI+ library, in the gdiplus!GetRECTSForPlayback function, while trying to display a malformed EMF+ image file:

(6be8.6f1c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=ffffadd6 ecx=000c1000 edx=00000000 esi=0000348f edi=00000000
eip=6c83a189 esp=0023f21c ebp=0023f238 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010216
6c83a189 8a11            mov     dl,byte ptr [ecx]          ds:002b:000c1000=??
0:000> kb
ChildEBP RetAddr  Args to Child              
0023f238 6c83c8a3 000001e0 00000018 00000800 gdiplus!GetRECTSForPlayback+0xe2
0023f294 6c8387e3 07b6bcb0 0000403a 00008800 gdiplus!SetTSClipEPR::Play+0x71
0023f2b4 6c83a88d 0000403a 00008800 00000018 gdiplus!GdipPlayMetafileRecordCallback+0x35
0023f2e4 6c83e32c 00000278 000c013c 000c0000 gdiplus!MetafilePlayer::EnumerateEmfPlusRecords+0x73
0023f2fc 76cd58a4 070125f7 04e18ff8 000c0098 gdiplus!EnumEmfWithDownLevel+0x61
0023f388 6c83abb4 070125f7 403581b3 6c83e2cb GDI32!bInternalPlayEMF+0x6a3
0023f3c0 6c83e5b1 070125f7 08462d83 0023f440 gdiplus!MetafilePlayer::EnumerateEmfRecords+0x104
0023f460 6c83f592 42776037 08462d83 0023f598 gdiplus!GpGraphics::EnumEmfPlusDual+0x1e7
0023f5b0 6c8448c9 00000000 42cc0000 42d80000 gdiplus!GpMetafile::EnumerateForPlayback+0x778
0023f6ac 6c84494d 07b65f28 00000000 00000000 gdiplus!GpGraphics::DrawImage+0x3f5
0023f710 6c80e03f 07b65f28 0023f738 0023f748 gdiplus!GpGraphics::DrawImage+0x51
0023f778 6c80e0d3 07b61d28 4269b097 00000000 gdiplus!GdipDrawImage+0x130
0023f7a4 000e1747 07b61d28 07b65f28 00000000 gdiplus!GdipDrawImageI+0x49

The crash appears to be caused by insufficient validation of the record size in relation to the number of declared rectangles, in the handler of the EmfPlusSetTSClip EMF+ record. It is unclear if the bug can also lead to memory corruption (likely not), but it could still potentially lead to the disclosure of junk/out-of-bounds heap bytes.

The issue reproduces on Windows 7. It is easiest to reproduce with PageHeap enabled. In order to reproduce the problem with the provided samples, it might be necessary to use a custom program which displays images using GDI+, or any existing GDI+ client (such as Microsoft Office).

Attached is an archive with two samples, which trigger crashes at two different offsets within the gdiplus!GetRECTSForPlayback function.

Proof of Concept: