New issue
Advanced search Search tips
Starred by 2 users
Status: WontFix
Owner:
Closed: Nov 15
Cc:



Sign in to add a comment
Windows Kernel pool address leak via undocumented GetFontData feature in ATMFD
Project Member Reported by mjurczyk@google.com, Oct 20 Back to list
We have discovered that the OpenType ATMFD.DLL kernel-mode driver may disclose valid Session Pool Addresses to user-mode programs via an undocumented feature of the GetFontData API function (as handled by the win32k!NtGdiGetFontData syscall and later by a DrvQueryTrueTypeTable handler implemented in ATMFD). The interface is designed to allow callers to obtain data of specific, existing SFNT tables. However, the font driver also responds to an undocumented, magic value of 0x65626441 ('ebdA', reverse of 'Adbe'). Once it is encountered, the following conditions are also checked:

1) Offset is set to 0.
2) Buffer size is set to the length of a pointer in bytes (4 on x86 and 8 on x64).
3) Buffer address is not NULL.

If all of the above conditions are met, the affected function writes the address of the kernel-mode font object into the output buffer and returns. The behavior is illustrated in the following assembly snippet found in ATMFD.DLL on a fully patched Windows 7 32-bit:

--- cut ---
  .text:0001438E                 xor     edi, edi
  [...]
  .text:00014399                 mov     esi, [ebp+iFile]
  [...]
  .text:000143E0                 mov     edx, [ebp+ulTag]
  .text:000143E3                 cmp     edx, 65626441h
  .text:000143E9                 jnz     short loc_14409
  .text:000143EB                 cmp     [ebp+dpStart], edi
  .text:000143EE                 jnz     short loc_14409
  .text:000143F0                 push    4
  .text:000143F2                 pop     ecx
  .text:000143F3                 cmp     [ebp+cjBuf], ecx
  .text:000143F6                 jnz     short loc_14409
  .text:000143F8                 mov     eax, [ebp+pjBuf]
  .text:000143FB                 cmp     eax, edi
  .text:000143FD                 jz      short loc_14409
  .text:000143FF                 mov     [eax], esi
  .text:00014401                 mov     [ebp+retval], ecx
  .text:00014404                 jmp     loc_144A5
--- cut ---

It can also be confirmed by running the attached proof-of-concept program:

--- cut ---
  C:\>GetFontData.exe
  Leaked address: FF9FA020
--- cut ---

and verifying the address under WinDbg:

--- cut ---
  Breakpoint 0 hit
  ATMFD+0x43ff:
  974043ff 8930            mov     dword ptr [eax],esi

  kd> !pool esi
  Pool page ff9fa020 region is Paged session pool
  *ff9fa000 size:  328 previous size:    0  (Allocated) *Adbe
      Pooltag Adbe : Adobe's font driver
   ff9fa328 size:    8 previous size:  328  (Free)       ....
   ff9fa330 size:  560 previous size:    8  (Allocated)  Gh15
--- cut ---

The leak is mostly useful for attackers on Windows 7 and 8, as the disclosed address can be used as part of an exploit chain, to defeat the KASLR mitigation and gain insight into the kernel address space layout. On Windows 10 the address is much less attractive, as it originates from the address space of a sandboxed user-mode fontdrvhost.exe process.

The underlying problem here is not a programming error, but bad design. The code intentionally returns kernel-mode addresses, so that they can be later used by user-mode clients to identify fonts in requests made through the NamedEscape interface (specifically in the GetFontBbox, GetGlyphList and GetSIDList operations). The following code can be found in atmlib.dll, a user-mode library which implements the user-mode portion of the NamedEscape interface:

--- cut ---
  .text:50001A15                 push    4               ; cjBuffer
  .text:50001A17                 push    [ebp+pvBuffer]  ; pvBuffer
  .text:50001A1A                 push    eax             ; dwOffset
  .text:50001A1B                 push    65626441h       ; dwTable
  .text:50001A20                 push    [ebp+hdc]       ; hdc
  .text:50001A23                 call    ds:GetFontData(x,x,x,x,x)
--- cut ---

The correct fix for the issue is to change the means of identifying fonts to one that does not reveal internal ring-0 addresses of objects in memory.

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.

 
GetFontData.cpp
1.2 KB View Download
poc.otf
18.7 KB Download
Project Member Comment 1 by mjurczyk@google.com, Oct 23
Labels: Reported-2017-Oct-23
Project Member Comment 2 by mjurczyk@google.com, Oct 24
Labels: MSRC-41754
Project Member Comment 3 by mjurczyk@google.com, Nov 15
Labels: -Restrict-View-Commit
Status: WontFix
MSRC have responded that the bug is an inherent design weakness that cannot be addressed through a single security update, but would require significant restructuring of the system's address space management. As a result, the case was closed as a security issue on Microsoft's end, but will be tracked to be fixed in a future release of Windows 10.
WontFix usually implies no future discussion on an issue. Will there still be a deep dive P0 blog post on this vulnerability after the Windows 10 fix ships?
Sign in to add a comment