lovesuae / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

Windows Kernel ATMFD.DLL pool-based buffer underflow due to integer overflow in STOREWV #179

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
In the Windows kernel ATMFD.DLL (Adobe Type Manager Font Driver) implementation 
of the `STOREWV` instruction (othersubr 19) used by Multiple Master Fonts [1], 
values are copied from a so-called "WeightVector" (an internal, MM-specific 
array) into the transient array (also known as "BuildCharArray"). The starting 
index is obtained from the operand stack, as shown below in Hex-Rays decompiled 
pseudo-code:

---
--op_sp;
idx = *(op_sp + 1);

[...]

master_designs = font->master_designs;
if ( master_designs + idx > font->lenBuildCharArray )
{
  DbgPrint(
    &dword_57B00,
    "%s:%d: %s (%s)\n",
    "windows\\core\\ntgdi\\fondrv\\otfd\\bc\\t1interp.c",
    5890,
    "STOREWV beyond buildCharArray",
    "false");
  goto label_error;
}

---

or, in assembly:

---
.text:0003C33B                 movsx   esi, word ptr [edi+2]
[...]
.text:0003C383                 mov     ecx, [edx+284h]
.text:0003C389                 lea     eax, [ecx+esi]
.text:0003C38C                 cmp     eax, [edx+328h]
.text:0003C392                 ja      loc_3FA35

---

The "master_designs" variable is the size of the "WeightVector" array and can 
be anything from 2 to 16, while "idx" is a fully controlled 16-bit signed 
integer. If "idx" is a negative number, the check can be effectively bypassed, 
thus leading to a buffer underflow of the "BuildCharArray" pool-based 
allocation, by a maximum of 64 bytes (16 dwords):

---
if ( master_designs )
{
  buildchar_offset = idx;
  weight_vector = font->weight_vector;
  do
  {
    ++it;
    value = *weight_vector;
    weight_vector += 4;
    font->BuildCharArray[buildchar_offset] = value;
    ++buildchar_offset;
  }
  while ( it < font->master_designs );
  op_sp = tmp_op_sp;
  it = 0;
}

---

The vulnerability can be reproduced with Multiple Master Type1 fonts (i.e. 
fonts consisting of three files: .PFM, .PFM and .MMM), but also with regular 
Type1 fonts, provided that a PostScript "/WeightVector" array is present in the 
.PFB file header (preferably of length 16), and the following instruction 
sequence is used for one of the rendered glyphs:

---
-16 1 19 callother

---

This will overwrite 64 bytes in front of the transient array, corrupting 
Windows pool headers and leading to a bugcheck (full log can be found in 
"crash.txt"):

---
KERNEL_SECURITY_CHECK_FAILURE (139)
A kernel component has corrupted a critical data structure.  The corruption
could potentially allow a malicious user to gain control of this machine.
Arguments:
Arg1: 00000003, A LIST_ENTRY has been corrupted (i.e. double remove).
Arg2: 81be4b54, Address of the trap frame for the exception that caused the 
bugcheck
Arg3: 81be4a80, Address of the exception record for the exception that caused 
the bugcheck
Arg4: 00000000, Reserved

---

All versions of Windows up to 8.1 (regardless of bitness) are affected. 
Attached is a Proof of Concept Type1 font ("poc.pfm" + "poc.pfb") and its 
source code ("poc.pfa"). In order to trigger a system crash, it is sufficient 
to open the POC font in the Windows Font Viewer program.

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] http://en.wikipedia.org/wiki/Multiple_master_fonts

Original issue reported on code.google.com by mjurc...@google.com on 19 Nov 2014 at 5:22

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 4 Dec 2014 at 4:37

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 11 Dec 2014 at 10:19

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 4 Feb 2015 at 2:57

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 24 Mar 2015 at 10:07

GoogleCodeExporter commented 9 years ago

Original comment by cev...@google.com on 1 Apr 2015 at 12:11

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 20 Apr 2015 at 2:07

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 12 Jun 2015 at 4:03