New issue
Advanced search Search tips
Starred by 2 users
Status: Fixed
Owner:
Closed: Apr 2015
Cc:



Sign in to add a comment
Windows Kernel ATMFD.DLL off-by-x oob reads/writes relative to the operand stack
Project Member Reported by mjurczyk@google.com, Nov 18 2014 Back to list
The Type1/CFF CharString interpreter code in the Adobe Type Manager Font Driver (ATMFD.DLL) Windows kernel module does not perform nearly any verification that the operand stack is large enough to contain the required instruction operands, which can lead to up to "off-by-three" overreads and overwrites on the interpreter function stack.

Even though the out-of-bounds accesses can take place, a respective "if (op_sp < op_stk)" check at the beginning of the next main loop iterations bails out, making it usually impossible (with one exception) to disclose values from the kernel stack or otherwise exploit most of those conditions. The vulnerable instructions that decrease "op_sp" (the operand stack pointer) below "&op_stk" (a local, 48-entry long array on the kernel stack) are:

1) escape + callothersubr
2) escape + callothersubr + endflex
3) escape + callothersubr + changehints
4) escape + callothersubr + counter{1, 2}
5) escape + add
6) escape + sub 
7) escape + mul
8) escape + div2
9) escape + put
10) escape + get
11) escape + ifelse
12) escape + and
13) escape + or
14) escape + eq
15) escape + roll
16) escape + setcurrentpoint
17) escape + load
18) escape + store

Furthermore, the following opcodes can perform out-of-bounds stack reads without successively bailing out, thus making it possible to leak the value(s) from the kernel stack:

1) escape + dup

The bugs are reproducible with both Type1 and OTF fonts. They are not very serious issues (to our knowledge, only one of the affected operators makes it possible to disclose four bytes from the kernel stack per glyph), but they are illustrative of the overall code quality of the interpreter code found in the Windows kernel. We have checked several builds of the ATMFD.DLL file to see if the three DWORDs immediately below "op_stk" were useful for exploitation (e.g. stored function pointers), but cursory analysis showed that no control-flow related data was stored there in the tested DLLs, which doesn't come as a surprise considering the enormous function stack frame (0x6f4 bytes on Windows 8.1 32-bit).

POC samples are not attached, but it is generally sufficient to invoke any of the above instructions when the operand stack is empty (e.g. at the very beginning of a CharString stream). All Windows editions up to 8.1 are affected (regardless of their bitness).

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.
 
Project Member Comment 1 by mjurczyk@google.com, Nov 18 2014
Labels: -Severity-Low Severity-Medium
On top of the above out-of-bounds reads, there are also multiple CharString instructions whose implementation doesn't verify that there is enough room on the stack to store their output values. This can lead to overwriting up to two 32-bit values before "&op_stk" on the kernel-mode stack.

The affected opcodes are as follows:

1) escape + not (off-by-one)
2) escape + neg (off-by-one)
3) escape + abs (off-by-one)
4) escape + sqrt (off-by-one)
5) escape + index (off-by-one)
6) escape + exch (off-by-two)

All of those instruction sequences follow a scheme of:

1) pop the instruction operand(s) from stack,
2) perform corresponding calculations,
3) push the operand(s) back to the stack.

While as a result they do not change the size of the stack, if the number of items on the stack is not sufficiently large, memory from before the operand stack will be used (and modified). The stack-based out-of-bounds write primitive is potentially dangerous here, but the fact that it is limited to mostly four bytes (with the exception of the "exch" instruction) and that there don't seem to be any interesting objects stored directly before the operand stack array in the ATMFD.DLL builds we have checked mitigates the risk of successful exploitation.

However, the mitigating factor is purely accidental and may not be present in future builds of the library, so it's recommended the bugs are treated as potentially allowing execution of arbitrary code.
Project Member Comment 2 by mjurczyk@google.com, Dec 4 2014
Labels: -Product-Windows Product-Kernel
Project Member Comment 3 by mjurczyk@google.com, Dec 11 2014
Labels: Reported-2014-Dec-10 MSRC-21197
Project Member Comment 4 by mjurczyk@google.com, Mar 24 2015
Labels: CVE-2015-0088
Comment 5 by cevans@google.com, Apr 1 2015
Status: Fixed
Project Member Comment 6 by mjurczyk@google.com, Apr 20 2015
Labels: Fixed-2015-Mar-10
Project Member Comment 7 by mjurczyk@google.com, Jun 12 2015
Labels: -Restrict-View-Commit
Any chance you have a PoC sample lying around that you could attach? Thanks!
Sign in to add a comment