Microsoft Windows Kernel ATMFD.DLL Out-Of-Bounds Read

The Microsoft Windows OpenType ATMFD.DLL kernel-mode driver lacks any sort of sanitization of various 32-bit offsets found in .MMM files (Multiple Master Metrics), and instead uses them blindly while loading Type 1 Multiple-Master fonts in the system.

MD5 | 870a4dbf54830a3b7fe3d330142d98ab

Windows Kernel ATMFD.DLL out-of-bounds read due to malformed offsets in MMM file 


We have discovered that the Windows OpenType ATMFD.DLL kernel-mode driver lacks any sort of sanitization of various 32-bit offsets found in .MMM files (Multiple Master Metrics), and instead uses them blindly while loading Type 1 Multiple-Master fonts in the system.

The corresponding code for handling .PFM files (Type 1 font metrics) performs thorough sanitization of all offsets and data, in a ValidatePFMPointers() function called by SetupPFMMetrics(), before using any of the checked values. However, SetupMMMMetrics() misses an analogous ValidateMMMPointers() routine, which may lead to accessing out-of-bounds memory while parsing malformed fonts. On 32-bit platforms, this is equivalent to allowing arbitrary memory reads relative to the user-mode address of the .MMM file mapping in the CSRSS.EXE process, which can reference memory in both the ring-3 and ring-0 memory areas.

While the specific structure of .MMM files is unclear, we have determined that they contain at least four types of blindly trusted offsets: three at positions 0x154, 0x158 and 0x15c, and a table of a maximum of 15 offsets pointed to by the offset at 0x154. Setting any of them to an out-of-bounds value may result in crashing the font driver, or potentially disclosing private memory from the kernel or the CSRSS.EXE process. The impact of the bug is highest on Windows 7 and 8, as Windows 10 has a sandboxed user-mode font driver (fontdrvhost.exe) that doesn't have access to any sensitive information and will cleanly restart upon crashing.

When the value at offset 0x15c is set to 0xcccccccc and such a font is loaded via AddFontResource() on Windows 7 32-bit, the following system bugcheck can be observed:

--- cut ---
Invalid system memory was referenced. This cannot be protected by try-except.
Typically the address is just plain bad or it is pointing at freed memory.
Arg1: cd52cccc, memory referenced.
Arg2: 00000000, value 0 = read operation, 1 = write operation.
Arg3: 820f9107, If non-zero, the instruction address which referenced the bad memory
Arg4: 00000002, (reserved)

TRAP_FRAME: 8f469750 -- (.trap 0xffffffff8f469750)
ErrCode = 00000000
eax=cd52cccc ebx=00860000 ecx=cd52cccd edx=cd52cccc esi=ff9fa588 edi=00860000
eip=820f9107 esp=8f4697c4 ebp=8f469818 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
820f9107 8a18 mov bl,byte ptr [eax] ds:0023:cd52cccc=??
Resetting default scope

LAST_CONTROL_TRANSFER: from 828d529b to 8285baa8

8f4692b4 828d529b 00000003 87964c01 00000065 nt!RtlpBreakWithStatusInstruction
8f469304 828d5d99 00000003 829459d0 c03354b0 nt!KiBugCheckDebugBreak+0x1c
8f4696c8 828618dd 00000050 cd52cccc 00000000 nt!KeBugCheck2+0x68b
8f469738 8283ab18 00000000 cd52cccc 00000000 nt!MmAccessFault+0xbd
8f469738 820f9107 00000000 cd52cccc 00000000 nt!KiTrap0E+0xdc
WARNING: Stack unwind information not available. Following frames may be wrong.
8f469818 820f6ed9 0d542d6a fe6f0848 00000000 ATMFD+0x9107
8f469888 820f3d14 fe6f08c8 00003274 85839102 ATMFD+0x6ed9
8f46996c 82187b8d 00000003 fe6f0848 ffa6aa48 ATMFD+0x3d14
8f4699b4 82187adf 00000003 fe6f0848 ffa6aa48 win32k!PDEVOBJ::LoadFontFile+0x3c
8f4699f4 821874fc ffbac008 0000003f fe6f0848 win32k!vLoadFontFileView+0x291
8f469a80 82176403 8f469b58 0000003f 00000003 win32k!PUBLIC_PFTOBJ::bLoadFonts+0x209
8f469acc 821773d8 8f469b58 0000003f 00000003 win32k!GreAddFontResourceWInternal+0xfb
8f469c14 82837936 001a2f10 0000003f 00000003 win32k!NtGdiAddFontResourceW+0x142
8f469c14 77ab6c74 001a2f10 0000003f 00000003 nt!KiSystemServicePostCall
0015f950 00000000 00000000 00000000 00000000 ntdll!KiFastSystemCallRet
--- cut ---

Similarly, when such a malformed font is loaded in Windows 10 32-bit, the following exception is generated in fontdrvhost.exe:

--- cut ---
Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
001b:00347404 8a02 mov al,byte ptr [edx]

0: kd> ? edx
Evaluate expression: -817247028 = cf49cccc

0: kd> k
# ChildEBP RetAddr
00 03b4f904 00339a71 fontdrvhost!SetupMMMMetrics+0x191
01 03b4f994 00339771 fontdrvhost!LoadFontInternal+0x22a
02 03b4f9f0 0033669e fontdrvhost!LoadFont+0x97
03 03b4fae4 00306460 fontdrvhost!DrvLoadFontFile+0x2be
04 03b4fb1c 0032412b fontdrvhost!DispatchRequest+0x24d
05 03b4fb90 75849ba4 fontdrvhost!ServerRequestLoop+0x7b
06 03b4fba4 77b0ac9b KERNEL32!BaseThreadInitThunk+0x24
07 03b4fbec 77b0ac6f ntdll!__RtlUserThreadStart+0x2b
08 03b4fbfc 00000000 ntdll!_RtlUserThreadStart+0x1b
--- cut ---

This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.

Found by: mjurczyk

Related Posts