How does the .NET CF handle null reference

Hyderabad Microsoft Campus

What happens when we have code as bellow

class B
    public virtual void Virt(){

class Program
    static void Main(string[] args){
        B b = null;
        b.Virt(); // throws System.NullReferenceException

Obviously we have a null reference exception being thrown. If you see the IL the call looks like

    L_0000: nop 
    L_0001: ldnull 
    L_0002: stloc.0 
    L_0003: ldloc.0 
    L_0004: callvirt instance void ConsoleApplication1.B::Virt()
    L_0009: nop 
    L_000a: ret 

So in effect you’d expect the jitter to generate the following kind of code (in processor instruction)

if (b == null)
   throw new NullReferenceException
   b->Virt() // actually call safely using the this pointer

However, generating null checks for every call is going to lead to code bloat. So to work around this on some platforms (e.g. .NETCF on WinCE 6.0 and above) it uses the following approach

  1. Hook up native access violation exception (WinCE 6.0 supports this) to a method in the execution engine (EE)
  2. Do not generate any null checking and directly generate calls through references
  3. In case the reference is null then a native AV (access violation is raised as invalid 0 address is accessed) and the hook method is called
  4. At this point the EE checks to see if the source of the access violation (native code) is inside Jitted code block. If yes it creates the managed NullRefenceException and propagates it up the call chain.
  5. If it’s outside then obviously it’s either CLR itself or some other native component is crashing and it has nothing to do about it..
Comments (3)

  1. Timothy Fries says:

    What sort of checks are in place to prevent this from being a security vulnerability?

    The JITted code isn’t going to be trying to jump to address 0; it’s going to be jumping to [0 + method offset].  In a way similar to how the recent arbitrary code execution exploit in Flash worked, could a user create a class with a virtual method table where a method offset is large enough that, after adding it to a null pointer, the resulting jump is to an executable page?

    I can imagine a VMT that large would break the EE in some way long before it got to that point.

  2. I’m definitely not a security expert. However, how do you propose a user "create a class with a virtual method table". Remember the user specifies a class and it’s methods in IL and the Jitter creates the method table.

  3. Timothy Fries says:

    The JIT creates the method table based off the class definition; and the class definition comes from an external source, so if the behavior of the JIT with regards to laying out the method table is known, an attacker could define a class with say, several million methods, to bump the pointer offset high enough that it would jump into a valid page when added to the null pointer.

    The same behavior (relying on an access violation to detect a null reference) was one of the key elements of the Flash vulnerability, due to a null pointer being accessed with an offset that made it a valid pointer.

    I grant that something else in the EE would probably fail out long before it became a security concern in this way when faced with a class with enough methods to where an offset would bump address 0 up to a real address, since I imagine you’d end up hitting an OOM condition while dealing with the class’s source definition.  Do you know if there’s actually a designed limit to class sizes that would cut off the potential of having a large method table?