New issue
Advanced search Search tips
Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Closed: Apr 2015
Cc:



Sign in to add a comment
link

Issue 177: Windows Kernel ATMFD.DLL read/write-what-where in LOAD and STORE operators

Reported by mjurczyk@google.com, Nov 19 2014 Project Member

Issue description

The "Type 2 Charstring Format" specification from 5 May 1998 specified two storage operators which were later removed from the document: `store` and `load`. These operators were responsible for copying data between the transient array (also known as the BuildCharArray) and the so-called "Registry object" (also deprecated by now, but still supported by Adobe implementations).

As the specs state:

"""
    The Registry provides more permanent storage for a number of items that have predefined meanings. The items stored in the Registry do not persist beyond the scope of rendering a font. Registry items are selected with an index, thus:

    0 Weight Vector
    1 Normalized Design Vector
    2 User Design Vector

    The result of selecting a Registry item with an index outside this list is undefined.
"""

However, the parameter sanity checking implemented for both operators - although present - is flawed. There is an off-by-one error in the verification of the Registry index, allowing for index 3 to be used:

---
.text:0003CA35                 cmp     eax, 3
.text:0003CA38                 ja      loc_3BEC4       ; jumptable 0003BF69 case 2
---

Internally, the Registry is implemented as a three-item array of structures similar to the following:

---
struct REGISTRY_ITEM {
  int32 size;
  void *data;
} Registry[3];
---

Accessing the 4th element of the array results in a reference to uninitialized memory from the Session Paged Pool. If the value of the "size" field happens to be positive, the "data" pointer is used as the "source" parameter of a "memcpy" call in case of the `load` instruction, and as "dest" in case of `store`.

With the ability to perform kernel pool massaging, it is possible to transform the bug into a read/write-what-where primitive by controlling the contents of the uninitialized memory used as source/destination addresses, which then easily leads to elevation of privileges and full system security compromise.

The issue is reproducible with Type1 and OTF fonts -- attached are reproducers for both formats, which can be opened in the standard Windows Font Viewer utility to trigger a bugcheck. Please note that in order for the system to crash, the "size" field must be positive and the "data" pointer must point into kernel-mode memory (ATMFD.DLL silently catches exceptions caused by invalid user-mode references), so it might require a few attempts. On the other hand, a local exploit is believed to be able to take advantage of the vulnerability with near 100% reliability.

If the kernel pool is sprayed such that size=0x55555555 and data=0xaaaaaaaa, the following bugcheck is triggered on a fully patched Windows 8.1 32-bit:

---
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: aaaaaaaa, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: 994f8c00, If non-zero, the instruction address which referenced the bad memory
    address.
Arg4: 00000002, (reserved)
---

A full crash log can be found in "crash.txt".

This bug is subject to a 90 day disclosure deadline. If 90 days elapse without a broadly available patch, then the bug report will automatically become visible to the public.
 
poc.pfb
19.6 KB Download
poc.pfm
668 bytes Download
crash.txt
5.8 KB View Download
poc.otf
86.4 KB Download

Comment 1 by mjurczyk@google.com, Dec 4 2014

Project Member
Labels: -Product-Windows Product-Kernel

Comment 2 by mjurczyk@google.com, Dec 11 2014

Project Member
Labels: Reported-2014-Dec-10 MSRC-21199

Comment 3 by mjurczyk@google.com, Mar 24 2015

Project Member
Labels: CVE-2015-0090

Comment 4 by cevans@google.com, Apr 1 2015

Status: Fixed

Comment 5 by mjurczyk@google.com, Apr 20 2015

Project Member
Labels: Fixed-2015-Mar-10

Comment 6 by mjurczyk@google.com, Jun 12 2015

Project Member
Labels: -Restrict-View-Commit

Sign in to add a comment