<feed xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
    <title>Simon Cooper</title>
    <link rel="self" type="application/xml" href="http://geekswithblogs.net/simonc/Atom.aspx" />
    <subtitle type="html">Peering into the depths of .NET</subtitle>
    <id>http://geekswithblogs.net/simonc/Default.aspx</id>
    <author>
        <name>simonc</name>
        <uri>http://geekswithblogs.net/simonc/Default.aspx</uri>
    </author>
    <generator uri="http://subtextproject.com" version="Subtext Version 0.0.0.0">Subtext</generator>
    <updated>2013-06-03T13:30:55Z</updated>
    <entry>
        <title>Why unhandled exceptions are useful</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/06/03/why-unhandled-exceptions-are-useful.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/06/03/why-unhandled-exceptions-are-useful.aspx</id>
        <published>2013-06-03T12:42:2601:00:00</published>
        <updated>2013-06-03T13:30:55Z</updated>
        <content type="html">&lt;p&gt;It's the bane of most programmers' lives - an unhandled exception causes your application or webapp to crash, an ugly dialog gets displayed to the user, and they come complaining to you. Then, somehow, you need to figure out what went wrong. Hopefully, you've got a log file, or some other way of reporting unhandled exceptions (obligatory employer plug: &lt;a href="http://www.red-gate.com/products/dotnet-development/smartassembly/"&gt;SmartAssembly&lt;/a&gt; reports an application's unhandled exceptions straight to you, along with the entire state of the stack and variables at that point). If not, you have to try and replicate it yourself, or do some psychic debugging to try and figure out what's wrong.&lt;/p&gt;

&lt;p&gt;However, it's good that the program crashed. Or, more precisely, it is correct behaviour. An unhandled exception in your application means that, somewhere in your code, there is an assumption that you made that is actually invalid.&lt;/p&gt;

&lt;h4&gt;Coding assumptions&lt;/h4&gt;
&lt;p&gt;Let me explain a bit more. Every method, every line of code you write, depends on implicit assumptions that you have made. Take this following simple method, that copies a collection to an array and includes an item if it isn't in the collection already, using a supplied IEqualityComparer:&lt;/p&gt;

&lt;pre&gt;public static T[] ToArrayWithItem(
    ICollection&amp;lt;T&amp;gt; coll, T obj, IEqualityComparer&amp;lt;T&amp;gt; comparer)
{
    // check if the object is in collection already
    // using the supplied comparer
    foreach (var item in coll)
    {
        if (comparer.Equals(item, obj))
        {
            // it's in the collection already
            // simply copy the collection to an array
            // and return it
            T[] array = new T[coll.Count];
            coll.CopyTo(array, 0);
            return array;
        }
    }
    
    // not in the collection
    // copy coll to an array, and add obj to it
    // then return it
    T[] array = new T[coll.Count+1];
    coll.CopyTo(array, 0);
    array[array.Length-1] = obj;
    return array;
}&lt;/pre&gt;
&lt;p&gt;What's all the assumptions made by this fairly simple bit of code?
&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;coll&lt;/code&gt; is never null&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comparer&lt;/code&gt; is never null&lt;/li&gt;
&lt;li&gt;&lt;code&gt;coll.CopyTo(array, 0)&lt;/code&gt; will copy all the items in the collection into the array, in the order defined for the collection, starting at the first item in the array.&lt;/li&gt;
&lt;li&gt;The enumerator for &lt;code&gt;coll&lt;/code&gt; returns all the items in the collection, in the order defined for the collection&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comparer.Equals&lt;/code&gt; returns true if the items are equal (for whatever definition of 'equal' the comparer uses), false otherwise&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comparer.Equals&lt;/code&gt;, &lt;code&gt;coll.CopyTo&lt;/code&gt;, and the &lt;code&gt;coll&lt;/code&gt; enumerator will never throw an exception or hang for any possible input and any possible values of &lt;code&gt;T&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;coll&lt;/code&gt; will have less than 4 billion items in it (this is a built-in limit of the CLR)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;array&lt;/code&gt; won't be more than 2GB, both on 32 and 64-bit systems, for any possible values of &lt;code&gt;T&lt;/code&gt; (again, a limit of the CLR)&lt;/li&gt;
&lt;li&gt;There are no threads that will modify &lt;code&gt;coll&lt;/code&gt; while this method is running&lt;/li&gt;
&lt;/ol&gt;
and, more esoterically:
&lt;ol start="10"&gt;
&lt;li&gt;The C# compiler will compile this code to IL according to the C# specification&lt;/li&gt;
&lt;li&gt;The CLR and JIT compiler will produce machine code to execute the IL on the user's computer&lt;/li&gt;
&lt;li&gt;The computer will execute the machine code correctly&lt;/li&gt;
&lt;/ol&gt;
That's a lot of assumptions. Now, it could be that all these assumptions
 are valid for the situations this method is called. But if this does 
crash out with an exception, or crash later on, then that shows one of 
the assumptions has been invalidated somehow.&lt;p&gt;&lt;/p&gt;

&lt;p&gt;An unhandled exception shows that your code is running in a situation which you did not anticipate, and there is something about how your code runs that you do not understand. Debugging the problem is the process of learning more about the new situation and how your code interacts with it. When you understand the problem, the solution is (usually) obvious. The solution may be a one-line fix, the rewrite of a method or class, or a large-scale refactoring of the codebase, but whatever it is, the fix for the crash will incorporate the new information you've gained about your own code, along with the modified assumptions.&lt;/p&gt;

&lt;p&gt;When code is running with an assumption or invariant it depended on broken, then the result is 'undefined behaviour'. Anything can happen, up to and including formatting the entire disk or making the user's computer sentient and start doing a good impression of Skynet. You might think that those can't happen, but at &lt;a href="http://en.wikipedia.org/wiki/Halting_problem"&gt;Halting problem&lt;/a&gt; levels of generality, as soon as an assumption the code depended on is broken, the program can do &lt;em&gt;anything&lt;/em&gt;. That is why it's important to fail-fast and stop the program as soon as an invariant is broken, to minimise the damage that is done.&lt;/p&gt;
 
&lt;h4&gt;What does this mean in practice?&lt;/h4&gt;
&lt;p&gt;To start with, document and check your assumptions. As with most things, there is a level of judgement required. How you check and document your assumptions depends on how the code is used (that's some more assumptions you've made), how likely it is a method will be passed invalid arguments or called in an invalid state, how likely it is the assumptions will be broken, how expensive it is to check the assumptions, and how bad things are likely to get if the assumptions are broken.&lt;/p&gt;

&lt;p&gt;Now, some assumptions you can assume unless proven otherwise. You can safely assume the C# compiler, CLR, and computer all run the method correctly, unless you have evidence of a compiler, CLR or processor bug. You can also assume that interface implementations work the way you expect them to; implementing an interface is more than simply declaring methods with certain signatures in your type. The behaviour of those methods, and how they work, is part of the interface contract as well.&lt;/p&gt;

&lt;p&gt;For example, for members of a public API, it is very important to document your assumptions and check your state before running the bulk of the method, throwing &lt;code&gt;ArgumentException&lt;/code&gt;, &lt;code&gt;ArgumentNullException&lt;/code&gt;, &lt;code&gt;InvalidOperationException&lt;/code&gt;, or another exception type as appropriate if the input or state is wrong. For internal and private methods, it is less important. If a private method expects collection items in a certain order, then you don't necessarily need to explicitly check it in code, but you can add comments or documentation specifying what state you expect the collection to be in at a certain point. That way, anyone debugging your code can immediately see what's wrong if this does ever become an issue. You can also use &lt;code&gt;DEBUG&lt;/code&gt; preprocessor blocks and &lt;code&gt;Debug.Assert&lt;/code&gt; to document and check your assumptions without incurring a performance hit in release builds.&lt;/p&gt;

&lt;h4&gt;On my coding soapbox...&lt;/h4&gt;
&lt;p&gt;A few pet peeves of mine around assumptions. Firstly, catch-all try blocks:
&lt;/p&gt;&lt;pre&gt;try
{
    ...
}
catch { }&lt;/pre&gt;
A catch-all hides exceptions generated by broken assumptions, and lets the program carry on in an unknown state. Later, an exception is likely to be generated due to further broken assumptions due to the unknown state, causing difficulties when debugging as the catch-all has hidden the original problem. It's much better to let the program crash straight away, so you know where the problem is. You should only use a catch-all if you are sure that &lt;em&gt;any&lt;/em&gt; exception generated in the try block is safe to ignore. That's a pretty big ask!&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Secondly, using &lt;code&gt;as&lt;/code&gt; when you should be casting. Doing this:
&lt;/p&gt;&lt;pre&gt;(obj as IFoo).Method();&lt;/pre&gt;
or this:
&lt;pre&gt;IFoo foo = obj as IFoo;
...
foo.Method();&lt;/pre&gt;
when you should be doing this:
&lt;pre&gt;((IFoo)obj).Method();&lt;/pre&gt;
or this:
&lt;pre&gt;IFoo foo = (IFoo)obj;
...
foo.Method();&lt;/pre&gt;
There's an assumption here that &lt;code&gt;obj&lt;/code&gt; will always implement &lt;code&gt;IFoo&lt;/code&gt;. If it doesn't, then by using &lt;code&gt;as&lt;/code&gt; instead of a cast you've turned an obvious &lt;code&gt;InvalidCastException&lt;/code&gt; at the point of the cast that will probably tell you what type &lt;code&gt;obj&lt;/code&gt; actually is, into a non-obvious &lt;code&gt;NullReferenceException&lt;/code&gt; at some later point that gives you no information at all. If you believe &lt;code&gt;obj&lt;/code&gt; is always an &lt;code&gt;IFoo&lt;/code&gt;, then say so in code! Let it fail-fast if not, then it's far easier to figure out what's wrong.&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Thirdly, document your assumptions. If an algorithm depends on a non-trivial relationship between several objects or variables, then say so. A single-line comment will do. Don't leave it up to whoever's debugging your code after you to figure it out.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;It's better to crash out and fail-fast when an assumption is broken. If it doesn't, then there's likely to be further crashes along the way that hide the original problem. Or, even worse, your program will be running in an undefined state, where &lt;em&gt;anything&lt;/em&gt; can happen. Unhandled exceptions aren't good per-se, but they give you some very useful information about your code that you didn't know before. And that can only be a good thing.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/153044.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/153044.aspx</wfw:comment>
        <slash:comments>10</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/153044.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/153044.aspx</trackback:ping>
    </entry>
    <entry>
        <title>.NET Security Part 4</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/05/28/152998.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/05/28/152998.aspx</id>
        <published>2013-05-28T12:14:4501:00:00</published>
        <updated>2013-05-28T12:16:45Z</updated>
        <content type="html">&lt;p&gt;Finally, in this series, I am going to cover some of the security issues that can trip you up when using sandboxed appdomains.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DISCLAIMER:&lt;/strong&gt; I am not a security expert, and this is by no means an exhaustive list. If you actually are writing security-critical code, then get a proper security audit of your code by a professional. The examples below are just illustrations of the sort of things that can go wrong.&lt;/p&gt;

&lt;h4&gt;1. AppDomainSetup.ApplicationBase&lt;/h4&gt;
&lt;p&gt;The most obvious one is the issue covered in the MSDN documentation on &lt;a href="http://msdn.microsoft.com/en-us/library/bb763046.aspx#code-snippet-4"&gt;creating a sandbox&lt;/a&gt;, in step 3 - the sandboxed appdomain has the same ApplicationBase as the controlling appdomain. So let's explore what happens when they are the same, and an exception is thrown.&lt;/p&gt;
&lt;p&gt;In the sandboxed assembly, Sandboxed.dll (IPlugin is an interface in a partially-trusted assembly, with a single MethodToDoThings on it):&lt;/p&gt;

&lt;pre&gt;public class UntrustedPlugin : MarshalByRefObject, IPlugin
{
    // implements IPlugin.MethodToDoThings()
    public void MethodToDoThings()
    {
        throw new EvilException();
    }
}

[Serializable]
internal class EvilException : Exception
{
    public override string ToString()
    {
        // show we have read access to C:\Windows
        // read the first 5 directories
        Console.WriteLine("Pwned! Mwuahahah!");
        foreach (var d in
            Directory.EnumerateDirectories(@"C:\Windows").Take(5))
        {
            Console.WriteLine(d.FullName);
        }
        return base.ToString();
    }
}&lt;/pre&gt;
&lt;p&gt;And in the controlling assembly:&lt;/p&gt;

&lt;pre&gt;// what can possibly go wrong?
AppDomainSetup appDomainSetup = new AppDomainSetup {
    ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
}

// only grant permissions to execute
// and to read the application base, nothing else
PermissionSet restrictedPerms = new PermissionSet(PermissionState.None);
restrictedPerms.AddPermission(
    new SecurityPermission(SecurityPermissionFlag.Execution));
restrictedPerms.AddPermission(
    new FileIOPermission(FileIOPermissionAccess.Read,
        appDomainSetup.ApplicationBase);
restrictedPerms.AddPermission(
    new FileIOPermission(FileIOPermissionAccess.pathDiscovery,
        appDomainSetup.ApplicationBase);

// create the sandbox
AppDomain sandbox = AppDomain.CreateDomain(
    "Sandbox", null, appDomainSetup, restrictedPerms);

// execute UntrustedPlugin in the sandbox
// don't crash the application if the sandbox throws an exception
IPlugin o = (IPlugin)sandbox.CreateInstanceFromAndUnwrap(
    "Sandboxed.dll", "UntrustedPlugin");
try
{
    o.MethodToDoThings()
}
catch (Exception e)
{
    Console.WriteLine(e.ToString());
}&lt;/pre&gt;
&lt;p&gt;And the result?&lt;/p&gt;
&lt;img src="https://gwb.blob.core.windows.net/simonc/NET-Security-Part-4_152998/Security%204%20pwned_-1621698560.png" width="550" /&gt;
&lt;p&gt;Oops. We've allowed a class that should be sandboxed to execute code with fully-trusted permissions! How did this happen? Well, the key is the exact meaning of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomainsetup.applicationbase.aspx"&gt;ApplicationBase&lt;/a&gt; property:&lt;/p&gt;

&lt;blockquote&gt;The application base directory is where the assembly manager begins probing for assemblies.&lt;/blockquote&gt;
&lt;p&gt;When &lt;code&gt;EvilException&lt;/code&gt; is thrown, it propagates from the sandboxed appdomain into the controlling assembly's appdomain (as it's marked as Serializable). When the exception is deserialized, the CLR finds and loads the sandboxed dll into the fully-trusted appdomain. Since the controlling appdomain's ApplicationBase directory contains the sandboxed assembly, the CLR finds and loads the assembly into a full-trust appdomain, and the evil code is executed.&lt;/p&gt;
&lt;p&gt;So the problem isn't exactly that the sandboxed appdomain's ApplicationBase is the same as the controlling appdomain's, it's that the sandboxed dll was in such a place that the controlling appdomain could find it as part of the standard assembly resolution mechanism. The sandbox then forced the assembly to load in the controlling appdomain by throwing a serializable exception that propagated outside the sandbox.&lt;/p&gt;
&lt;p&gt;The easiest fix for this is to keep the sandbox ApplicationBase well away from the ApplicationBase of the controlling appdomain, and don't allow the sandbox permissions to access the controlling appdomain's ApplicationBase directory. If you do this, then the sandboxed assembly can't be accidentally loaded into the fully-trusted appdomain, and the code can't be executed. If the plugin does try to induce the controlling appdomain to load an assembly it shouldn't, a SerializationException will be thrown when it tries to load the assembly to deserialize the exception, and no damage will be done.&lt;/p&gt;

&lt;h4&gt;2. Loading the sandboxed dll into the application appdomain&lt;/h4&gt;
&lt;p&gt;As an extension of the previous point, you shouldn't directly reference types or methods in the sandboxed dll from your application code. That loads the assembly into the fully-trusted appdomain, and from there code in the assembly could be executed. Instead, pull out methods you want the sandboxed dll to have into an interface or class in a partially-trusted assembly you control, and execute methods via that instead (similar to the example above with the &lt;code&gt;IPlugin&lt;/code&gt; interface).&lt;/p&gt;
&lt;p&gt;If you need to have a look at the assembly before executing it in the sandbox, either examine the assembly using reflection from within the sandbox, or load the assembly into the &lt;a href="http://msdn.microsoft.com/en-us/library/ms172331.aspx"&gt;Reflection-only context&lt;/a&gt; in the application's appdomain. The code in assemblies in the reflection-only context can't be executed, it can only be reflected upon, thus protecting your appdomain from malicious code.&lt;/p&gt;

&lt;h4&gt;3. Incorrectly asserting permissions&lt;/h4&gt;
&lt;p&gt;You should only assert permissions when you are absolutely sure they're safe. For example, this method allows a caller read-access to any file they call this method with, including your documents, any network shares, the C:\Windows directory, etc:&lt;/p&gt;

&lt;pre&gt;[SecuritySafeCritical]
public static string GetFileText(string filePath)
{
    new FileIOPermission(FileIOPermissionAccess.Read, filePath).Assert();
    return File.ReadAllText(filePath);
}&lt;/pre&gt;
&lt;p&gt;Be careful when asserting permissions, and ensure you're not providing a loophole sandboxed dlls can use to gain access to things they shouldn't be able to.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;Hopefully, that's given you an idea of some of the ways it's possible to get past the .NET security system. As I said before, this post is not exhaustive, and you certainly shouldn't base any security-critical applications on the contents of this blog post. What this series should help with is understanding the possibilities of the security system, and what all the security attributes and classes mean and what they are used for, if you were to use the security system in the future.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/152998.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/152998.aspx</wfw:comment>
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/152998.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/152998.aspx</trackback:ping>
    </entry>
    <entry>
        <title>.NET Security Part 3</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/05/16/.net-security-part-3.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/05/16/.net-security-part-3.aspx</id>
        <published>2013-05-16T17:52:0001:00:00</published>
        <updated>2013-05-16T17:55:21Z</updated>
        <content type="html">&lt;p&gt;You write a security-related application that allows addins to be used. These addins (as dlls) can be downloaded from anywhere, and, if allowed to run full-trust, could open a security hole in your application. So you want to restrict what the addin dlls can do, using a sandboxed appdomain, as explained in my previous posts.&lt;/p&gt;

&lt;p&gt;But there needs to be an interaction between the code running in the sandbox and the code that created the sandbox, so the sandboxed code can control or react to things that happen in the controlling application. Sandboxed code needs to be able to call code outside the sandbox.&lt;/p&gt;

&lt;p&gt;Now, there are various methods of allowing cross-appdomain calls, the two main ones being &lt;a href="http://msdn.microsoft.com/en-us/library/kwdt6w2k.aspx"&gt;.NET Remoting&lt;/a&gt; with &lt;a href="http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.aspx"&gt;MarshalByRefObject&lt;/a&gt;, and WCF named pipes. I'm not going to cover the details of setting up such mechanisms here, or which you should choose for your specific situation; there are plenty of blogs and tutorials covering such issues elsewhere. What I'm going to concentrate on here is the more general problem of running fully-trusted code within a sandbox, which is required in most methods of app-domain communication and control.&lt;/p&gt;

&lt;h4&gt;Defining assemblies as fully-trusted&lt;/h4&gt;

&lt;p&gt;In my last post, I mentioned that when you create a sandboxed appdomain, you can pass in a list of assembly strongnames that run as full-trust within the appdomain:&lt;/p&gt;

&lt;pre&gt;// get the Assembly object for the assembly
Assembly assemblyWithApi = ...    

// get the StrongName from the assembly's collection of evidence
StrongName apiStrongName = assemblyWithApi.Evidence.GetHostEvidence&amp;lt;StrongName&amp;gt;();

// create the sandbox
AppDomain sandbox = AppDomain.CreateDomain(
    "Sandbox", null, appDomainSetup, restrictedPerms, apiStrongName);&lt;/pre&gt;
    
&lt;p&gt;Any assembly that is loaded into the sandbox with a strong name the same as one in the list of full-trust strong names is unconditionally given full-trust permissions within the sandbox, irregardless of permissions and sandbox setup. This is very powerful! You should only use this for assemblies that you trust as much as the code creating the sandbox.&lt;/p&gt;

&lt;p&gt;So now you have a class that you want the sandboxed code to call:&lt;/p&gt;

&lt;pre&gt;// within assemblyWithApi
public class MyApi
{
    public static void MethodToDoThings() { ... }
}

// within the sandboxed dll
public class UntrustedSandboxedClass
{
    public void DodgyMethod()
    {        
        ...
        MyApi.MethodToDoThings();
        ...
    }
}&lt;/pre&gt;

&lt;p&gt;However, if you try to do this, you get quite an ugly exception:
&lt;/p&gt;&lt;blockquote&gt;MethodAccessException: Attempt by security transparent method 'UntrustedSandboxedClass.DodgyMethod()' to access security critical method 'MyApi.MethodToDoThings()' failed.&lt;/blockquote&gt;
Security transparency, which I covered in my first post in the series, has entered the picture. Partially-trusted code runs at the Transparent security level, fully-trusted code runs at the Critical security level, and Transparent code cannot under any circumstances call Critical code.

&lt;h4&gt;Security transparency and AllowPartiallyTrustedCallersAttribute&lt;/h4&gt;

&lt;p&gt;So the solution is easy, right? Make &lt;code&gt;MethodToDoThings&lt;/code&gt; SafeCritical, then the transparent code running in the sandbox can call the api:&lt;/p&gt;
&lt;pre&gt;[SecuritySafeCritical]
public static void MethodToDoThings() { ... }&lt;/pre&gt;
&lt;p&gt;However, this doesn't solve the problem. When you try again, exactly the same exception is thrown; MethodToDoThings is still running as Critical code. What's going on?&lt;/p&gt;

&lt;p&gt;By default, a fully-trusted assembly always runs Critical code, irregardless of any security attributes on its types and methods. This is because it may not have been designed in a secure way when called from transparent code - as we'll see in the next post, it is easy to open a security hole despite all the security protections .NET 4 offers. When exposing an assembly to be called from partially-trusted code, the entire assembly needs a security audit to decide what should be transparent, safe critical, or critical, and close any potential security holes.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.allowpartiallytrustedcallersattribute.aspx"&gt;AllowPartiallyTrustedCallersAttribute&lt;/a&gt; (APTCA) comes in. Without this attribute, fully-trusted assemblies run Critical code, and partially-trusted assemblies run Transparent code. When this attribute is applied to an assembly, it confirms that the assembly has had a full security audit, and it is safe to be called from untrusted code. All code in that assembly runs as Transparent, but &lt;code&gt;SecurityCriticalAttribute&lt;/code&gt; and &lt;code&gt;SecuritySafeCriticalAttribute&lt;/code&gt; can be applied to individual types and methods to make those run at the Critical or SafeCritical levels, with all the restrictions that entails.&lt;/p&gt;

&lt;p&gt;So, to allow the sandboxed assembly to call the full-trust API assembly, simply add APCTA to the API assembly:&lt;/p&gt;
&lt;pre&gt;[assembly: AllowPartiallyTrustedCallers]&lt;/pre&gt;
&lt;p&gt;and everything works as you expect. The sandboxed dll can call your API dll, and from there communicate with the rest of the application.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;That's the basics of running a full-trust assembly in a sandboxed appdomain, and allowing a sandboxed assembly to access it. The key is AllowPartiallyTrustedCallersAttribute, which is what lets partially-trusted code call a fully-trusted assembly. However, an assembly with APTCA applied to it means that you have run a full security audit of every type and member in the assembly. If you don't, then you could inadvertently open a security hole. I'll be looking at ways this can happen in my next post.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/152935.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/152935.aspx</wfw:comment>
        <slash:comments>4</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/152935.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/152935.aspx</trackback:ping>
    </entry>
    <entry>
        <title>.NET Security Part 2</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/05/07/.net-security-part-2.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/05/07/.net-security-part-2.aspx</id>
        <published>2013-05-07T16:15:3901:00:00</published>
        <updated>2013-05-07T18:18:54Z</updated>
        <content type="html">&lt;p&gt;So, how do you create partial-trust appdomains? Where do you come across them?&lt;/p&gt;
&lt;p&gt;There are two main situations in which your assembly runs as partially-trusted using the Microsoft .NET stack:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Creating a CLR assembly in SQL Server with anything other than the &lt;code&gt;UNSAFE&lt;/code&gt; permission set. The permissions available in each permission set are given &lt;a href="http://msdn.microsoft.com/en-us/library/ms345101.aspx"&gt;here&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;Loading an assembly in ASP.NET in any trust level other than Full. Information on ASP.NET trust levels can be found &lt;a href="http://msdn.microsoft.com/en-us/library/wyts434y.aspx"&gt;here&lt;/a&gt;. You can configure the specific permissions available to assemblies using ASP.NET policy files.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alternatively, you can create your own partially-trusted appdomain in code and directly control the permissions and the full-trust API available to the assemblies you load into the appdomain. This is the scenario I'll be concentrating on in this post.&lt;/p&gt;

&lt;h4&gt;Creating a partially-trusted appdomain&lt;/h4&gt;
&lt;p&gt;There is a single overload of &lt;code&gt;AppDomain.CreateDomain&lt;/code&gt; that allows you to specify the permissions granted to assemblies in that appdomain - &lt;a href="http://msdn.microsoft.com/en-us/library/ms130766.aspx"&gt;this one&lt;/a&gt;. This is the only call that allows you to specify a &lt;code&gt;PermissionSet&lt;/code&gt; for the domain. All the other calls simply use the permissions of the calling code. If the permissions are restricted, then the resulting appdomain is referred to as a &lt;em&gt;sandboxed&lt;/em&gt; domain.&lt;/p&gt;
&lt;p&gt;There are three things you need to create a sandboxed domain:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;The specific permissions granted to all assemblies in the domain.&lt;/li&gt;
	&lt;li&gt;The application base (aka working directory) of the domain.&lt;/li&gt;
	&lt;li&gt;The list of assemblies that have full-trust if they are loaded into the sandboxed domain.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The third item is what allows us to have a fully-trusted API that is callable by partially-trusted code. I'll be looking at the details of this in a later post.&lt;/p&gt;

&lt;h4&gt;Granting permissions to the appdomain&lt;/h4&gt;
&lt;p&gt;Firstly, the permissions granted to the appdomain. This is encapsulated in a &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.permissionset.aspx"&gt;PermissionSet&lt;/a&gt; object, initialized either with no permissions or full-trust permissions. For sandboxed appdomains, the PermissionSet is initialized with no permissions, then you add permissions you want assemblies loaded into that appdomain to have by default:&lt;/p&gt;

&lt;pre&gt;PermissionSet restrictedPerms = new PermissionSet(PermissionState.None);

// all assemblies need Execution permission to run at all
restrictedPerms.AddPermission(
    new SecurityPermission(SecurityPermissionFlag.Execution));

// grant general read access to C:\config.xml
restrictedPerms.AddPermission(
    new FileIOPermission(FileIOPermissionAccess.Read, @"C:\config.xml"));

// grant permission to perform DNS lookups
restrictedPerms.AddPermission(
    new DnsPermission(PermissionState.Unrestricted));&lt;/pre&gt;
&lt;p&gt;It's important to point out that the permissions granted to an appdomain, and so to all assemblies loaded into that appdomain, are usable without needing to go through any SafeCritical code (see my last post if you're unsure what SafeCritical code is). That is, partially-trusted code loaded into an appdomain with the above permissions (and so running under the Transparent security level) is able to create and manipulate a &lt;code&gt;FileStream&lt;/code&gt; object to read from C:\config.xml directly. It is only for operations requiring permissions that are &lt;em&gt;not&lt;/em&gt; granted to the appdomain that partially-trusted code is required to call a SafeCritical method that then asserts the missing permissions and performs the operation safely on behalf of the partially-trusted code.&lt;/p&gt;

&lt;h4&gt;The application base of the domain&lt;/h4&gt;
&lt;p&gt;This is simply set as a property on an &lt;code&gt;AppDomainSetup&lt;/code&gt; object, and is used as the default directory assemblies are loaded from:&lt;/p&gt;

&lt;pre&gt;AppDomainSetup appDomainSetup = new AppDomainSetup {
    ApplicationBase = @"C:\temp\sandbox",
};&lt;/pre&gt;
&lt;p&gt;If you've read the documentation around sandboxed appdomains, you'll notice that it mentions a security hole if this parameter is set correctly. I'll be looking at this, and other pitfalls, that will break the sandbox when using sandboxed appdomains, in a later post.&lt;/p&gt;

&lt;h4&gt;Full-trust assemblies in the appdomain&lt;/h4&gt;
&lt;p&gt;Finally, we need the strong names of the assemblies that, when loaded into the appdomain, will be run as full-trust, irregardless of the permissions specified on the appdomain. These assemblies will contain methods and classes decorated with SafeCritical and Critical attributes. I'll be covering the details of creating full-trust APIs for partial-trust appdomains in a later post. This is how you get the strongnames of an assembly to be executed as full-trust in the sandbox:&lt;/p&gt;

&lt;pre&gt;// get the Assembly object for the assembly
Assembly assemblyWithApi = ...    

// get the StrongName from the assembly's collection of evidence
StrongName apiStrongName = assemblyWithApi.Evidence.GetHostEvidence&amp;lt;StrongName&amp;gt;();&lt;/pre&gt;
&lt;h4&gt;Creating the sandboxed appdomain&lt;/h4&gt;
&lt;p&gt;So, putting these three together, you create the appdomain like so:&lt;/p&gt;
&lt;pre&gt;AppDomain sandbox = AppDomain.CreateDomain(
    "Sandbox", null, appDomainSetup, restrictedPerms, apiStrongName);&lt;/pre&gt;
&lt;p&gt;You can then load and execute assemblies in this appdomain like any other. For example, to load an assembly into the appdomain and get an instance of the &lt;code&gt;Sandboxed.Entrypoint&lt;/code&gt; class, implementing &lt;code&gt;IEntrypoint&lt;/code&gt;, you do this:&lt;/p&gt;

&lt;pre&gt;IEntrypoint o = (IEntrypoint)sandbox.CreateInstanceFromAndUnwrap(
    "C:\temp\sandbox\SandboxedAssembly.dll", "Sandboxed.Entrypoint");

// call method the Execute method on this object within the sandbox
o.Execute();&lt;/pre&gt;
&lt;p&gt;The second parameter to &lt;code&gt;CreateDomain&lt;/code&gt; is for security evidence used in the appdomain. This was a feature of the .NET 2 security model, and has been (mostly) obsoleted in the .NET 4 model. Unless the evidence is needed elsewhere (eg. isolated storage), you can pass in null for this parameter.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;That's the basics of sandboxed appdomains. The most important object is the PermissionSet that defines the permissions available to assemblies running in the appdomain; it is this object that defines the appdomain as full or partial-trust. The appdomain also needs a default directory used for assembly lookups as the ApplicationBase parameter, and you can specify an optional list of the strongnames of assemblies that will be given full-trust permissions if they are loaded into the sandboxed appdomain.&lt;/p&gt;
&lt;p&gt;Next time, I'll be looking closer at full-trust assemblies running in a sandboxed appdomain, and what you need to do to make an API available to partial-trust code.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/152885.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/152885.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/152885.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/152885.aspx</trackback:ping>
    </entry>
    <entry>
        <title>.NET Security Part 1</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/05/02/.net-security-part-1.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/05/02/.net-security-part-1.aspx</id>
        <published>2013-05-02T17:51:5801:00:00</published>
        <updated>2013-05-02T17:53:54Z</updated>
        <content type="html">&lt;p&gt;Ever since the first version of .NET, it's been possible to strictly define the actions and resources a particular assembly can use, and, using Code Access Security, permissions to perform certain actions or access certain resources can be defined and modified in code. In .NET 4, the system was completely overhauled. Today, I'll be starting a look at what the security model is in .NET 4, how you use it, and what you can do with it.&lt;/p&gt;

&lt;h4&gt;Partial and full-trust assemblies&lt;/h4&gt;

&lt;p&gt;Most developers aren't affected by the .NET 4 security model. This is because it only affects assemblies loaded as partial-trust. All assemblies loaded directly on a desktop system, either as part of a desktop application, or a web application on a full-trust appdomain (the default), or loaded as &lt;code&gt;UNSAFE&lt;/code&gt; into SQL Server, run as full trust. This means they have full access to the system, and can do whatever they want with no restrictions.&lt;/p&gt;

&lt;p&gt;But when an assembly is loaded into a partial-trust appdomain, the actions and resources it can access are limited to the permissions that are granted to it. For example, partially-trusted code can only read a file on disk if it's have explicitly been given &lt;code&gt;FileIOPermission&lt;/code&gt; to read the file. And code can only access the registry if it's been given &lt;code&gt;RegistryPermission&lt;/code&gt; to do so (all the available permissions that can be granted and denied from partial-trust assemblies inherit from &lt;code&gt;System.Security.CodeAccessPermission&lt;/code&gt;). This is to limit what untrusted assemblies can do, and stop assemblies containing potentially damaging code from accessing the system and doing something it shouldn't (say, format the disk).&lt;/p&gt;

&lt;p&gt;When a certain permission is required to perform an action, the &lt;em&gt;entire&lt;/em&gt; call stack leading up to the call performing that action (for example, &lt;code&gt;File.OpenRead&lt;/code&gt; or &lt;code&gt;Registry.OpenSubKey&lt;/code&gt;) is checked for that permission. If there is &lt;em&gt;any&lt;/em&gt; method on the call stack that is running as partial-trust, and has not explicitly been granted the required permission, then the call fails with a &lt;code&gt;SecurityException&lt;/code&gt;, even if the partially-trusted method that failed the permission check is many stackframes down.&lt;/p&gt;

&lt;p&gt;This ensures that there is no way for partially-trusted code to get round permissions that haven't been granted to it by delegating to or exploiting something else that does have the permission. If the partial-trust code is running, then it is on the call stack. And if it's on the call stack, then it cannot directly or indirectly perform actions that it hasn't been given permissions for.&lt;/p&gt;

&lt;p&gt;But this is a problem - there are legitimate situations in which partially-trusted code needs to perform security-critical actions, even if it hasn't been given permissions to do so directly. For example, a desktop application (running as full trust) loads an addin into a partial trust appdomain. The desktop app provides an API to the addin to update values in a configuration file on disk, but doesn't grant general read-write access to the config file. However, when the addin tries to update the config file through the API provided by the full-trust application, such updates will always fail with a &lt;code&gt;SecurityException&lt;/code&gt;, because the partial-trust code in the addin doesn't have permissions to write to the filesystem, even though it is the full-trust code that is actually writing to the config file.&lt;/p&gt;

&lt;p&gt;So, there needs to be a way for full-trust code to override the permission check in a secure way such that it can perform security-critical actions on behalf of partial-trust code, once it has verified the partial-trust code is not misbehaving. There are two features that allow this - permission asserts, and security transparency.&lt;/p&gt;

&lt;h4&gt;Permission demands and asserts&lt;/h4&gt;

&lt;p&gt;To start a stack walk to check for a certain permission, you simply demand it, either using a method call:&lt;/p&gt;
&lt;pre&gt;public void UpdateConfigFile(string propName, bool newValue)
{
    new FileIOPermission(FileIOPermissionAccess.Write, "C:\config.xml").Demand();
    // .. write to the file ..
}&lt;/pre&gt;
or using an attribute, which demands the permission when the method is called. This is functionally identical to calling &lt;code&gt;Demand()&lt;/code&gt; as the first statement in the method:
&lt;pre&gt;[FileIOPermission(SecurityAction.Demand, Write = "C:\config.xml")]
public void UpdateConfigFile(string propName, bool newValue)
{
    // .. write to the file ..
}&lt;/pre&gt;

&lt;p&gt;(Note that demanding a FileIOPermission directly isn't normally required, as the BCL methods that access the filesystem all demand the appropriate permissions themselves).&lt;/p&gt;

&lt;p&gt;Then, to stop a stack walk for a permission from checking past the current stack frame and hitting partially-trusted code, you assert the same permission before calling the method that demands it. Again, you can do this in code:&lt;/p&gt;
&lt;pre&gt;public void ChangeConfigProperty(string propName, bool newValue)
{
    new FileIOPermission(FileIOPermissionAccess.Write, "C:\config.xml").Assert();
    UpdateConfigFile("C:\config.xml", propName, newValue);
}&lt;/pre&gt;
or using an attribute:
&lt;pre&gt;[FileIOPermission(SecurityAction.Assert, Write = "C:\config.xml")]
public void ChangeConfigProperty(string propName, bool newValue)
{
    UpdateConfigFile("C:\config.xml", propName, newValue);
}&lt;/pre&gt;

&lt;p&gt;After a permission has been asserted, any security check for that permission triggered by method calls after that point in the same method stops at that stack frame.&lt;/p&gt;

&lt;p&gt;For this to be effective, there has to be a way to stop partially trusted code from simply asserting whatever permissions it wants, but still being able to call trusted code that can assert those permissions. This is where security transparency comes in.&lt;/p&gt;

&lt;h4&gt;Security transparency&lt;/h4&gt;

&lt;p&gt;There are three security levels code runs under - Transparent, SafeCritical, and Critical. Each imposes restrictions on what the code can do and what it can call, independant of any code access permissions applied to it:
&lt;/p&gt;&lt;dl&gt;

&lt;dt&gt;&lt;code&gt;Transparent&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;This is the security level all partially-trusted code runs under. There are several restrictions imposed on transparent code; in particular, transparent code cannot do the following:
&lt;ul&gt;
&lt;li&gt;Call Critical-security code (but it can call SafeCritical code).&lt;/li&gt;
&lt;li&gt;Assert additional permissions.&lt;/li&gt;
&lt;li&gt;Contain unsafe or unverifiable code.&lt;/li&gt;
&lt;li&gt;Call P/Invoke methods.&lt;/li&gt;
&lt;li&gt;Override or inherit Critical types and methods.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;

&lt;dt&gt;&lt;code&gt;SafeCritical&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;This is the 'broker' between Transparent and Critical-security code. Transparent code cannot call Critical code directly, but it can call SafeCritical code, which in turn can call Critical code. SafeCritical code verifies the caller isn't trying to do something it shouldn't, then either performs the action itself or passes it to a Critical method. There is no restriction on what SafeCritical code can do.&lt;/dd&gt;

&lt;dt&gt;&lt;code&gt;Critical&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;This is the level all fully-trusted code runs under. There is no restriction on what Critical code can do.&lt;/dd&gt;
&lt;/dl&gt;

This diagram shows the relationships between the different levels, and what each level can call (green represents allowed method calls between levels, red disallowed calls):

&lt;img src="http://i.msdn.microsoft.com/ee677170.dai_figure3(en-us,MSDN.10).png" /&gt;

&lt;h4&gt;Putting it together&lt;/h4&gt;

&lt;p&gt;Permission asserts and security transparency allow a partially-trusted assembly (running transparent-security code) to call an API in a fully-trusted assembly (running Critical and SafeCritical code) to perform actions that the partially-trusted assembly doesn't itself have permissions for:&lt;/p&gt;
&lt;pre&gt;public void PartiallyTrustedMethod()
{
    ChangeConfigProperty("Enabled", true);
}

[SecuritySafeCritical]
public void ChangeConfigProperty(string propName, bool newValue)
{
    // check propName isn't too long,
    // escape any sequences that could be dangerous
    Sanitise(propName);
    
    // assert that its ok to write to the config file
    new FileIOPermission(FileIOPermissionAccess.Write, "C:\config.xml").Assert();
    
    UpdateConfigFile("C:\config.xml", propName, newValue);
}

[SecurityCritical]
public void UpdateConfigFile(string file, string propName, bool newValue)
{
    // this demands Write permission to the config file
    File.WriteAllLines(file, new[] { "propName = " + newValue });
}&lt;/pre&gt;

&lt;p&gt;Next time, we'll look at how you create a partially-trusted appdomain in your own code, and how you can run fully-trusted code in a partially-trusted appdomain.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/152841.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/152841.aspx</wfw:comment>
        <slash:comments>4</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/152841.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/152841.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Inside Portable Class Libraries</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/04/19/inside-portable-class-libraries.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/04/19/inside-portable-class-libraries.aspx</id>
        <published>2013-04-19T15:41:1801:00:00</published>
        <updated>2013-04-19T15:41:18Z</updated>
        <content type="html">&lt;p&gt;Portable Class Libraries were introduced with Visual Studio 2010 SP1 to aid writing libraries that could be used on many different platforms - the full .NET 4/4.5 framework, Windows Phone, Silverlight, Xbox, and Windows Store apps. You simply select which platforms and versions you want to target, then the available subset of APIs are magically available. But how does it work? How does Visual Studio know what it can target, and how does the same assembly run on many different platforms? Today, I'll be finding out.&lt;/p&gt;

&lt;h4&gt;Creating a Portable Class Library&lt;/h4&gt;

&lt;p&gt;When you create a PCL in Visual Studio, you select the platforms and versions you want to target. In this example, I've selected everything at the lowest available version. In the project references list, this turns into a generic '.NET Portable Subset', with no real identifying information as to what it actually is:&lt;/p&gt;

&lt;img src="http://www.simple-talk.com/blogbits/simon.cooper/PCL1.png" /&gt;

&lt;p&gt;Hmm, ok, well lets see what the actual built assembly does with it. Lets create a field of type &lt;code&gt;Action&amp;lt;T1,T2&amp;gt;&lt;/code&gt; so the assembly actually has something in it:
&lt;/p&gt;&lt;pre&gt;public class Class1 {
    Action&amp;lt;int, double&amp;gt; action = null;
}&lt;/pre&gt;

&lt;p&gt;After building the assembly, and opening it up in a decompiler, we can see that that mysterious '.NET Portable Subset' reference has turned into standard assembly references to mscorlib.dll and System.Core.dll. However, they look a bit odd:&lt;/p&gt;

&lt;pre&gt;mscorlib, Version=2.0.5.0, Culture=neutral,
    PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes
System.Core, Version=2.0.5.0, Culture=neutral,
    PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes&lt;/pre&gt;

&lt;p&gt;2.0.5.0 is the version number used by Silverlight assemblies, and that's the Silverlight public key, but that 'Retargetable' flag is new. And if you have a look at the assembly-level attributes, you'll spot something familiar:
&lt;/p&gt;&lt;pre&gt;[assembly: TargetFramework(
    ".NETPortable,Version=v4.0,Profile=Profile1",
    FrameworkDisplayName=".NET Portable Subset")]&lt;/pre&gt;
    
&lt;p&gt;Aha! There's the '.NET Portable Subset' from the Visual Studio reference list. But what about the target framework? &lt;code&gt;".NETPortable,Version=v4.0,Profile=Profile1"&lt;/code&gt;? What's that all about? Well, have a look in 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\'. In there is a list of every possible .NET 4 PCL subset you can target (22 in total). Within each profile directory are the available assemblies containing the types that can be used, and an xml file for each framework supported by that profile containing platform version information.&lt;/p&gt;

&lt;p&gt;These profile directories have been pre-calculated by Microsoft and installed alongside visual studio. When you create a PCL project, and select the platforms and versions you want supported, Visual Studio looks at all the available profiles and the framework versions they are valid for. From the version and platform information in each profile it works out the most applicable profile, and dlls in that profile are the ones it compiles the PCL assembly against and to provide intellisense support.&lt;/p&gt;

&lt;p&gt;But these dlls are useless at runtime. If you open one of the dlls in a decompiler, you'll see that all the method bodies are empty or simply return the default value for the return type. These dlls exist only to be referenced and compiled against.&lt;/p&gt;

&lt;h4&gt;Using a portable class library&lt;/h4&gt;

&lt;p&gt;So the dlls in the Reference Assemblies folder are, rather unsuprisingly, only to be referenced. Something else happens at runtime to make the portable library work on all the supported frameworks.&lt;/p&gt;

&lt;p&gt;It turns out that it all comes down to a feature of .NET assemblies that was introduced in .NET 2, and I looked at two years ago - &lt;a href="http://geekswithblogs.net/simonc/archive/2011/12/23/anatomy-of-a-.net-assembly---type-forwards.aspx"&gt;type forwards&lt;/a&gt;. In the portable class library I've built, the &lt;code&gt;System.Action`2&lt;/code&gt; type I've used has been resolved to the System.Core assembly. In different platforms, it may be in different places. But every platform will either contain the type in System.Core, or System.Core will have a type forward to where the type is actually located.&lt;/p&gt;

&lt;p&gt;So, as you'll see in the framework-specific reference assemblies, Silverlight 4, Windows Phone, and Xbox all have &lt;code&gt;System.Action`2&lt;/code&gt; located in their System.Core.dll, so the type is resolved successfully on those platforms. Both the desktop and Silverlight 5 System.Core.dll have a type forward for &lt;code&gt;System.Action`2&lt;/code&gt; to the relevant mscorlib.dll, where the type is actually located.&lt;/p&gt;

&lt;p&gt;Windows store applications (the framework for windows store applications is called '.NETCore') forward the type to System.Runtime.dll. And, if you take a further look at the System.Core.dll in the .NETCore framework, this assembly contains no types whatsoever! The only things in that assembly of any note are a series of type forwards to various other assemblies in the .NETCore framework - that assembly exists only to redirect type references in portable class libraries when they are used in Windows Store applications.&lt;/p&gt;

&lt;h4&gt;Cross-version assembly references&lt;/h4&gt;

&lt;p&gt;There is one more thing we need to sort out. If you have a look at the assembly references in the original PCL we built, they reference a specific version of mscorlib.dll and System.Core.dll:&lt;/p&gt;

&lt;pre&gt;mscorlib, Version=2.0.5.0, Culture=neutral,
    PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes
System.Core, Version=2.0.5.0, Culture=neutral,
    PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes&lt;/pre&gt;
    
&lt;p&gt;These versions are the same as the version numbers on Silverlight 4, Windows Phone, and Xbox framework assemblies. But the version of mscorlib for Silverlight 5 is:&lt;/p&gt;
&lt;pre&gt;mscorlib, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e&lt;/pre&gt;
and .NET 4 desktop and .NETCore:
&lt;pre&gt;mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/pre&gt;
&lt;p&gt;This is a problem. These assemblies all have strong name signatures, and the version &amp;amp; public key form part of the assembly's identity. An assembly reference to an assembly with version 2.0.5.0 and public key 7cec85d7bea7798e cannot be resolved to an assembly with version 4.0.0.0 and public key b77a5c561934e089. To the CLR, these are two completely different assemblies.&lt;/p&gt;

&lt;p&gt;That's where the Retargetable flag on the assembly references comes in. If this flag is on an assembly reference, it means the reference can resolve to an assembly with a different version and public key, even though it is technically a different assembly. This flag is on all the references to framework dlls in a PCL, and this means the PCL can run on different frameworks with different assembly versions and public keys. The framework dll references are resolved to the one available in the framework the library is executing on at runtime.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;There's nothing magic about portable class libraries. They are compiled just like any other assembly, but are compiled against a specific pre-defined subset of the libraries available in the different frameworks, defined by portable profiles representing the various combinations of types and methods available. When the library is executing on a specific framework at runtime, type fowards redirect any types that have been moved to a different assembly in that framework. The common CLR, assembly metadata and IL formats across all the frameworks and versions ensure the actual code logic in the assembly executes the same way on any available framework.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/152741.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/152741.aspx</wfw:comment>
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/152741.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/152741.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Subterranean IL: ThreadLocal revisited</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2013/04/18/subterranean-il-threadlocal-revisited.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2013/04/18/subterranean-il-threadlocal-revisited.aspx</id>
        <published>2013-04-18T17:09:3001:00:00</published>
        <updated>2013-04-18T17:12:01Z</updated>
        <content type="html">&lt;p&gt;Last year, I looked at the &lt;a href="http://geekswithblogs.net/simonc/archive/2012/05/03/subterranean-il-the-threadlocal-type.aspx"&gt;&lt;code&gt;ThreadLocal&lt;/code&gt;&lt;/a&gt; type as it exists in .NET 4. In .NET 4.5, this type has been completely rewritten. In this post, I'll be looking at how the new &lt;code&gt;ThreadLocal&lt;/code&gt; works in .NET 4.5. I won't be looking at all the implementation details, but concentrating on how this type works. Again, it's recommended you have the type open in a decompiler.&lt;/p&gt;

&lt;h4&gt;No More Generics!&lt;/h4&gt;
&lt;p&gt;The most obvious change is the lack of generic classes - it no longer uses generic instantiations to store individual thread static variables. Instead, it uses a design similar to that of &lt;a href="http://geekswithblogs.net/simonc/archive/2012/03/26/inside-the-concurrent-collections-concurrentbag.aspx"&gt;&lt;code&gt;ConcurrentBag&lt;/code&gt;&lt;/a&gt; - an array of values held in a thread static array, with each instance of &lt;code&gt;ThreadLocal&lt;/code&gt; being assigned its own index into that array, and linked lists between the items in each thread static array to allow access from any thread.&lt;/p&gt;
&lt;p&gt;The important variables here are the thread static &lt;code&gt;ts_slotArray&lt;/code&gt;, &lt;code&gt;m_idComplement&lt;/code&gt; and &lt;code&gt;m_linkedSlot&lt;/code&gt;. Each thread has its own &lt;code&gt;ts_slotArray&lt;/code&gt; instance, and each instance of &lt;code&gt;ThreadLocal&lt;/code&gt; has its own slot index into those arrays as &lt;code&gt;m_idComplement&lt;/code&gt; (I'm ignoring the fact that &lt;code&gt;ThreadLocal&lt;/code&gt; is generic for now; each generic instantiation of &lt;code&gt;ThreadLocal&lt;/code&gt; has its own static variables independant from any other). The list of all values stored in each instance is accessible through the linked list accessible from &lt;code&gt;m_linkedSlot&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, these extra links between arrays mean that the value to be stored can't be put straight into &lt;code&gt;ts_slotArray&lt;/code&gt;, you need an extra type to provide these links. This is where the &lt;code&gt;LinkedSlot&lt;/code&gt; type comes in - it provides a &lt;code&gt;Next&lt;/code&gt; and &lt;code&gt;Previous&lt;/code&gt; fields to link between slots in different arrays. This graph indicates how these different fields interact - the arrows represent the &lt;code&gt;Next&lt;/code&gt; and &lt;code&gt;Previous&lt;/code&gt; references between slots:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://www.simple-talk.com/blogbits/simon.cooper/ThreadLocal45.png" /&gt;&lt;/p&gt;
&lt;p&gt;Note that the instance of &lt;code&gt;LinkedSlot&lt;/code&gt; directly referenced by the &lt;code&gt;m_linkedSlot&lt;/code&gt; field is an empty instance that is not stored in any array; it exists only to be the target of another slot's &lt;code&gt;Previous&lt;/code&gt; field, and simplifies the logic in the other methods.&lt;/p&gt;

&lt;h4&gt;Setting values&lt;/h4&gt;
&lt;p&gt;Each instance of &lt;code&gt;ThreadLocal&lt;/code&gt; is assigned a unique index by the &lt;code&gt;IdManager&lt;/code&gt; class when it is created. When a thread first sets a value in an instance of &lt;code&gt;ThreadLocal&lt;/code&gt;, the following happens in &lt;code&gt;SetValueSlow&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;If the slot array hasn't been assigned for this thread (ie this is the first time this thread has accessed any instance of &lt;code&gt;ThreadLocal&lt;/code&gt;), it creates a new array to hold enough items for this instance's slot index.&lt;/li&gt;
	&lt;li&gt;If the array isn't big enough for this instance's slot index, it is resized so it is, and all the containing &lt;code&gt;LinkedSlot&lt;/code&gt;s are updated to point to the new array (in the &lt;code&gt;GrowTable&lt;/code&gt; method).&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;CreateLinkedSlot&lt;/code&gt; is called to create a new &lt;code&gt;LinkedSlot&lt;/code&gt; instance and store it in the array at the instance's slot index. It also adds it to the head of the linked list pointed to by &lt;code&gt;m_linkedSlot&lt;/code&gt; in this instance of &lt;code&gt;ThreadLocal&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Subsequently, when values are get &amp;amp; set, it gets and sets the value at the slot index owned by the &lt;code&gt;ThreadLocal&lt;/code&gt; being accessed, in the slot array for the accessing thread.&lt;/p&gt;

&lt;h4&gt;Removing and disposing of ThreadLocals&lt;/h4&gt;
&lt;p&gt;So that's what happens when values are set. What about when the thread is no longer running, or the &lt;code&gt;ThreadLocal&lt;/code&gt; is disposed? Both require values to be removed or unset in the arrays &amp;amp; untangled in the linked lists, else any values set will just stay there, won't be collected, and will cause a memory leak.&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;
&lt;h4&gt;&lt;code&gt;ThreadLocal.Dispose&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;When an instance of &lt;code&gt;ThreadLocal&lt;/code&gt; is disposed or finalized, it needs to clear the instances of &lt;code&gt;LinkedSlot&lt;/code&gt; in all the referenced slot arrays. Fortunately, this is quite easy to do - it simply iterates through the link list defined by &lt;code&gt;m_linkedSlot&lt;/code&gt;, and clears the entries. Finally, it returns the slot index it was using to the &lt;code&gt;IdManager&lt;/code&gt; class to be reused when the next instance of &lt;code&gt;ThreadLocal&lt;/code&gt; is created.&lt;/p&gt;
&lt;/li&gt;
	&lt;li&gt;
&lt;h4&gt;&lt;code&gt;Thread exit&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Dealing with a thread exit is harder, as there isn't a global event that fires whenever a thread exits. Fortunately, a little-known feature of thread statics can be used to clear up the slot array belonging to a thread that has exited.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Detecting thread exits&lt;/h4&gt;
&lt;p&gt;Normal static fields, once the type has been initialized, stay around until the AppDomain exits. That means that any object being referenced by a static field won't be collected until the field is explicitly cleared.&lt;/p&gt;
&lt;p&gt;However, thread static fields are different. The CLR keeps track of which threads are active, and which have exited. It can link this to the various values stored in a thread static field. This means that any value set on a thread static field belonging to a thread that has exited, and that isn't referenced by anything else, is eligible for garbage collection, and will be collected the next time the garbage collector runs.&lt;/p&gt;
&lt;p&gt;This feature is exploited by &lt;code&gt;ThreadLocal&lt;/code&gt; to clear up the slot arrays of exited threads. This is primarily performed by the &lt;code&gt;FinalizationHelper&lt;/code&gt; class, which is created and assigned to a thread static field when the slot array is first created and assigned.&lt;/p&gt;

&lt;h4&gt;FinalizationHelper&lt;/h4&gt;
&lt;p&gt;This class only exists for its finalizer. When a thread exits, the corresponding instance of &lt;code&gt;FinalizationHelper&lt;/code&gt; assigned to the &lt;code&gt;ts_finalizationHelper&lt;/code&gt; field becomes eligible for collection. If and when the garbage collector runs, this instance gets collected, and the finalizer is run. This finalizer removes any non-empty slots from the linked lists of active &lt;code&gt;ThreadLocal&lt;/code&gt; instances, unless the values are needed to be kept if a call to &lt;code&gt;ThreadLocal.Values&lt;/code&gt; is made to return all the values ever set on that instance.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;So there we are; the upgraded &lt;code&gt;ThreadLocal&lt;/code&gt;. It's an improvement on the old version, in that it allows access to all the values ever set on an instance of &lt;code&gt;ThreadLocal&lt;/code&gt;, it doesn't fallback on the thread local data store, and it doesn't pollute the namespace with thousands of generic instances of holder classes. Much better!&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/152732.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/152732.aspx</wfw:comment>
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/152732.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/152732.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Inside the DLR - Invoking methods</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2012/08/20/inside-the-dlr---invoking-methods.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2012/08/20/inside-the-dlr---invoking-methods.aspx</id>
        <published>2012-08-20T19:51:3301:00:00</published>
        <updated>2012-08-20T19:51:33Z</updated>
        <content type="html">&lt;p&gt;So, we've looked at how a dynamic call is represented in a compiled assembly, and how the dynamic lookup is performed at runtime. The last piece of the puzzle is how the resolved method gets invoked, and that is the subject of this post.&lt;/p&gt;

&lt;h4&gt;Invoking methods&lt;/h4&gt;
&lt;p&gt;As discussed in my previous posts, doing a full lookup and bind at runtime each and every single time the callsite gets invoked would be far too slow to be usable. The results obtained from the callsite binder must to be cached, along with a series of conditions to determine whether the cached result can be reused.&lt;/p&gt;
&lt;p&gt;So, firstly, how are the conditions represented? These conditions can be &lt;em&gt;anything&lt;/em&gt;; they are determined entirely by the semantics of the language the binder is representing. The binder has to be able to return arbitary code that is then executed to determine whether the conditions apply or not.&lt;/p&gt;
&lt;p&gt;Fortunately, .NET 4 has a neat way of representing arbitary code that can be easily combined with other code - expression trees. All the callsite binder has to return is an expression (called a 'restriction') that evaluates to a boolean, returning true when the restriction passes (indicating the corresponding method invocation can be used) and false when it does't. If the bind result is also represented in an expression tree, these can be combined easily like so:&lt;/p&gt;

&lt;pre&gt;if ([restriction is true]) {
    [invoke cached method]
}&lt;/pre&gt;
&lt;p&gt;Take my example from my previous post:&lt;/p&gt;

&lt;pre&gt;public class ClassA
{
    public static void TestDynamic()
    {
        CallDynamic(new ClassA(), 10);
        CallDynamic(new ClassA(), "foo");
    }

    public static void CallDynamic(dynamic d, object o)
    {
        d.Method(o);
    }

    public void Method(int i) {}
    public void Method(string s) {}
}&lt;/pre&gt;
&lt;p&gt;When the &lt;code&gt;Method(int)&lt;/code&gt; method is first bound, along with an expression representing the result of the bind lookup, the C# binder will return the restrictions under which that bind can be reused. In this case, it can be reused if the types of the parameters are the same:&lt;/p&gt;

&lt;pre&gt;if (thisArg.GetType() == typeof(ClassA) &amp;amp;&amp;amp; arg1.GetType() == typeof(int)) {
    thisClassA.Method(i);
}&lt;/pre&gt;
&lt;h4&gt;Caching callsite results&lt;/h4&gt;
&lt;p&gt;So, now, it's up to the callsite to link these expressions returned from the binder together in such a way that it can determine which one from the many it has cached it should use. This caching logic is all located in the &lt;code&gt;System.Dynamic.UpdateDelegates&lt;/code&gt; class. It'll help if you've got this type open in a decompiler to have a look yourself.&lt;/p&gt;
&lt;p&gt;For each callsite, there are 3 layers of caching involved:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;The last method invoked on the callsite.&lt;/li&gt;
	&lt;li&gt;All methods that have ever been invoked on the callsite.&lt;/li&gt;
	&lt;li&gt;All methods that have ever been invoked on any callsite of the same type.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We'll cover each of these layers in order&lt;/p&gt;

&lt;h4&gt;Level 1 cache: the last method called on the callsite&lt;/h4&gt;
&lt;p&gt;When a &lt;code&gt;CallSite&amp;lt;T&amp;gt;&lt;/code&gt; object is first instantiated, the &lt;code&gt;Target&lt;/code&gt; delegate field (containing the delegate that is called when the callsite is invoked) is set to one of the &lt;code&gt;UpdateAndExecute&lt;/code&gt; generic methods in &lt;code&gt;UpdateDelegates&lt;/code&gt;, corresponding to the number of parameters to the callsite, and the existance of any return value.&lt;/p&gt;
&lt;p&gt;These methods contain most of the caching, invoke, and binding logic for the callsite. The first time this method is invoked, the &lt;code&gt;UpdateAndExecute&lt;/code&gt; method finds there aren't any entries in the caches to reuse, and invokes the binder to resolve a new method.&lt;/p&gt;
&lt;p&gt;Once the callsite has the result from the binder, along with any restrictions, it stitches some extra expressions in, and replaces the &lt;code&gt;Target&lt;/code&gt; field in the callsite with a compiled expression tree similar to this (in this example I'm assuming there's no return value):&lt;/p&gt;

&lt;pre&gt;if ([restriction is true]) {
    [invoke cached method]
    return;
}

if (callSite._match) {
    _match = false;
    return;
}
else {
    UpdateAndExecute(callSite, arg0, arg1, ...);
}&lt;/pre&gt;
&lt;p&gt;Woah. What's going on here? Well, this resulting expression tree is actually the first level of caching. The &lt;code&gt;Target&lt;/code&gt; field in the callsite, which contains the delegate to call when the callsite is invoked, is set to the above code compiled from the expression tree into IL, and then into native code by the JIT. This code checks whether the restrictions of the last method that was invoked on the callsite (the 'primary' method) match, and if so, executes that method straight away.&lt;/p&gt;
&lt;p&gt;This means that, the next time the callsite is invoked, the first code that executes is the restriction check, executing as native code! This makes this restriction check on the primary cached delegate &lt;em&gt;very&lt;/em&gt; fast.&lt;/p&gt;
&lt;p&gt;But what if the restrictions don't match? In that case, the second part of the stitched expression tree is executed. What this section &lt;em&gt;should&lt;/em&gt; be doing is calling back into the &lt;code&gt;UpdateAndExecute&lt;/code&gt; method again to resolve a new method. But it's slightly more complicated than that. To understand why, we need to understand the second and third level caches.&lt;/p&gt;

&lt;h4&gt;Level 2 cache: all methods that have ever been invoked on the callsite&lt;/h4&gt;
&lt;p&gt;When a binder has returned the result of a lookup, as well as updating the &lt;code&gt;Target&lt;/code&gt; field with a compiled expression tree, stitched together as above, the callsite puts the same compiled expression tree in an internal list of delegates, called the rules list. This list acts as the level 2 cache.&lt;/p&gt;
&lt;p&gt;Why use the same delegate? Stitching together expression trees is an expensive operation. You don't want to do it every time the callsite is invoked. Ideally, you would create one expression tree from the binder's result, compile it, and then use the resulting delegate everywhere in the callsite.&lt;/p&gt;
&lt;p&gt;But, if the same delegate is used to invoke the callsite in the first place, and in the caches, that means each delegate needs two modes of operation. An 'invoke' mode, for when the delegate is set as the value of the &lt;code&gt;Target&lt;/code&gt; field, and a 'match' mode, used when &lt;code&gt;UpdateAndExecute&lt;/code&gt; is searching for a method in the callsite's cache. Only in the invoke mode would the delegate call back into &lt;code&gt;UpdateAndExecute&lt;/code&gt;. In match mode, it would simply return without doing anything.&lt;/p&gt;
&lt;p&gt;This mode is controlled by the &lt;code&gt;_match&lt;/code&gt; field in &lt;code&gt;CallSite&amp;lt;T&amp;gt;&lt;/code&gt;. The first time the callsite is invoked, &lt;code&gt;_match&lt;/code&gt; is false, and so the &lt;code&gt;Target&lt;/code&gt; delegate is called in invoke mode. Then, if the initial restriction check fails, the &lt;code&gt;Target&lt;/code&gt; delegate calls back into &lt;code&gt;UpdateAndExecute&lt;/code&gt;. This method sets &lt;code&gt;_match&lt;/code&gt; to true, then calls all the cached delegates in the rules list in match mode to try and find one that passes its restrictions, and invokes it.&lt;/p&gt;
&lt;p&gt;However, there needs to be some way for each cached delegate to inform &lt;code&gt;UpdateAndExecute&lt;/code&gt; whether it passed its restrictions or not. To do this, as you can see above, it simply re-uses &lt;code&gt;_match&lt;/code&gt;, and sets it to false if it did not pass the restrictions. This allows the code within each &lt;code&gt;UpdateAndExecute&lt;/code&gt; method to check for cache matches like so:&lt;/p&gt;

&lt;pre&gt;foreach (T cachedDelegate in Rules) {
    callSite._match = true;
    cachedDelegate();   // sets _match to false if restrictions do not pass
    if (callSite._match) {
        // passed restrictions, and the cached method was invoked
        // set this delegate as the primary target to invoke next time
        callSite.Target = cachedDelegate;
        return;
    }
    // no luck, try the next one...
}&lt;/pre&gt;
&lt;h4&gt;Level 3 cache: all methods that have ever been invoked on any callsite with the same signature&lt;/h4&gt;
&lt;p&gt;The reason for this cache should be clear - if a method has been invoked through a callsite in one place, then it is likely to be invoked on other callsites in the codebase with the same signature.&lt;/p&gt;
&lt;p&gt;Rather than living in the callsite, the 'global' cache for callsite delegates lives in the &lt;code&gt;CallSiteBinder&lt;/code&gt; class, in the &lt;code&gt;Cache&lt;/code&gt; field. This is a dictionary, typed on the callsite delegate signature, providing a &lt;code&gt;RuleCache&amp;lt;T&amp;gt;&lt;/code&gt; instance for each delegate signature. This is accessed in the same way as the level 2 callsite cache, by the &lt;code&gt;UpdateAndExecute&lt;/code&gt; methods. When a method is matched in the global cache, it is copied into the callsite and Target cache before being executed.&lt;/p&gt;

&lt;h4&gt;Putting it all together&lt;/h4&gt;
&lt;p&gt;So, how does this all fit together? Like so (I've omitted some implementation &amp;amp; performance details):&lt;/p&gt;
&lt;p&gt;&lt;img class="alignnone size-full wp-image-2196" src="http://www.simple-talk.com/blogs/wp-content/uploads/2012/08/DLR-3a2.png" alt="" width="501" height="462" /&gt;&lt;/p&gt;
&lt;p&gt;That, in essence, is how the DLR performs its dynamic calls nearly as fast as statically compiled IL code. Extensive use of expression trees, compiled to IL and then into native code. Multiple levels of caching, the first of which executes immediately when the dynamic callsite is invoked. And a clever re-use of compiled expression trees that can be used in completely different contexts without being recompiled. All in all, a very fast and very clever reflection caching mechanism.&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/150482.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/150482.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/150482.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/150482.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Inside the DLR – Callsite binders </title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2012/08/03/inside-the-dlr--callsite-binders.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2012/08/03/inside-the-dlr--callsite-binders.aspx</id>
        <published>2012-08-03T10:56:5601:00:00</published>
        <updated>2012-08-03T10:57:25Z</updated>
        <content type="html">&lt;p&gt;So, we've looked at how the C# compiler produces a &lt;code&gt;CallSite&lt;/code&gt; object for every dynamic call that is made, and provides it with everything it needs to resolve the call at runtime. How is this information used when the callsite is invoked?&lt;/p&gt;

&lt;p&gt;To create a &lt;code&gt;CallSite&lt;/code&gt; object, you need to pass in an instance of &lt;code&gt;CallSiteBinder&lt;/code&gt;, which performs the member lookup and binding of a dynamic call for the callsite. Each language has its own binder, and C#'s binder lives in the &lt;code&gt;Microsoft.CSharp.dll&lt;/code&gt; assembly. If you have a look at this assembly in a disassembler, you'll see that within this assembly, in the &lt;code&gt;Microsoft.CSharp.RuntimeBinder.Semantics&lt;/code&gt; namespace, is a copy of the type lookup and member resolution code from the C# compiler! However, rather than being native calls to C++ methods and classes, the logic has been modified to use normal .NET reflection types and methods, just like any other reflection-based code - &lt;code&gt;System.Type&lt;/code&gt;, &lt;code&gt;MethodInfo&lt;/code&gt;, &lt;code&gt;FieldInfo&lt;/code&gt;, &lt;code&gt;Type.GetInterfaces()&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;When a callsite is invoked, the &lt;code&gt;CallSiteBinder&lt;/code&gt; associated with that callsite takes the static information it was initialized with, combines it with information on the specific arguments the callsite was invoked with, and passes that information to a version of the C# compiler's type lookup logic in the &lt;code&gt;Microsoft.CSharp.dll&lt;/code&gt; assembly. This logic then uses standard .NET reflection calls to figure out what the call should resolve to, and passes that information back to the binder.&lt;/p&gt;

&lt;h4&gt;But what about speed?&lt;/h4&gt;

&lt;p&gt;However, there is a big problem with this: speed. Reflection is &lt;em&gt;slooooow&lt;/em&gt;. If this lookup had to be performed every time the callsite is invoked, then dynamic calls would simply be too slow to be usable. So, the callsite needs to cache the result obtained from the binder to be re-used the next time the callsite is invoked. But this leads onto another problem. Take the following code:&lt;/p&gt;

&lt;pre&gt;public class ClassA
{
    public static void TestDynamic()
    {
        CallDynamic(new ClassA(), 10);
        CallDynamic(new ClassA(), "foo");
    }

    public static void CallDynamic(dynamic d, object o)
    {
        d.Method(o);
    }
    
    public void Method(int i) {}
    public void Method(string s) {}
}&lt;/pre&gt;

&lt;p&gt;The first time the callsite in &lt;code&gt;CallDynamic&lt;/code&gt; is invoked, the C# binder will resolve the call to the &lt;code&gt;Method(int i)&lt;/code&gt; method. If this result is then cached and re-used for the second call, the &lt;code&gt;Method(int i)&lt;/code&gt; method will be called with a &lt;code&gt;string&lt;/code&gt; argument, and the dynamic call will fail with an exception. The C# binder's member resolution algorithm needs to be run again on the second call, to find a new method to call. This would then correctly resolve to the &lt;code&gt;Method(string s)&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;So, then, how can the callsite tell when a cached result can be re-used, and when it needs to call the binder to find a new method to call? Only the binder knows that, as it depends entirely on the binder's member resolution rules and the methods available on the invoked type.&lt;/p&gt;

&lt;p&gt;Therefore, when returning the result of a lookup, the binder also needs to return the conditions under which that result can be re-used. And before calling a cached result, the callsite needs to check the conditions apply before either calling the resolved method, or going back to the binder to resolve a new method.&lt;/p&gt;

&lt;h4&gt;Calling and caching&lt;/h4&gt;

&lt;p&gt;This leads onto the questions over how this is actually represented, and how the checks and caching can be done without sacrificing performance. Ideally, it would be just as fast as calling a method non-dynamically. Well, the fastest way to generate and execute arbitary code at runtime is to produce and compile a method in raw IL using &lt;code&gt;MethodBuilder&lt;/code&gt; and &lt;code&gt;ILGenerator&lt;/code&gt;. Unfortunately, these aren't very easy to use, especially when you need to link several methods together, which (as we'll see) is crucial to the behaviour of the callsite.&lt;/p&gt;

&lt;p&gt;However, .NET 4 provides a far easier solution - expression trees blocks. These provide a far easier way to generate and link together code at runtime, and it is these that provide the implementation of the checks and method invocations used by every callsite. My next post will focus on how these expression tree blocks are used to implement the caching and invocation within a dynamic callsite.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Cross posted from &lt;a href="http://www.simple-talk.com/blogs/author/24200-simon-cooper/"&gt;Simple Talk&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/150357.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/150357.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/150357.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/150357.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Inside the DLR - Callsites</title>
        <link rel="self" type="text/html" href="http://geekswithblogs.net/simonc/archive/2012/07/20/inside-the-dlr---callsites.aspx" />
        <id>http://geekswithblogs.net/simonc/archive/2012/07/20/inside-the-dlr---callsites.aspx</id>
        <published>2012-07-20T12:22:0001:00:00</published>
        <updated>2012-08-02T14:16:32Z</updated>
        <content type="html">&lt;p&gt;The DLR was introduced in .NET 4 to allow dynamic languages, like Python or Ruby, to run on the CLR. The DLR is also used by C# 4, released at the same time, to implement dynamic binding via the &lt;code&gt;dynamic&lt;/code&gt; keyword. In this post, I'll be looking at what exactly happens when you issue a dynamically-bound call in C#.&lt;/p&gt;

&lt;h4&gt;What is the DLR?&lt;/h4&gt;
&lt;p&gt;The Dynamic Language Runtime isn't a runtime. At least, not in the same way as the Common Language Runtime. The DLR is a library that runs on the CLR, just like any other arbitary assembly. The library itself is a large and complex beast, with hooks at all levels for various interoperability and extensibility scenarios. In this post, I'll only be looking at the core functionality - dynamically binding to methods and executing what is found quickly and efficiently.&lt;/p&gt;

&lt;h4&gt;Callsites&lt;/h4&gt;
&lt;p&gt;What happens when you compile a dynamically-bound statement in C#? Take the following example. This method contains a single dynamic invocation of something that looks like an instance method called &lt;code&gt;Func&lt;/code&gt;, that takes two integer arguments:

&lt;/p&gt;&lt;pre&gt;public void DynamicCall(dynamic d, int i)
{
    d.Func(10, i);
}&lt;/pre&gt;

When the C# compiler sees this, and notices that it's a dynamically bound call, it doesn't generate a normal method call using &lt;code&gt;call&lt;/code&gt; or &lt;code&gt;callvirt&lt;/code&gt; IL instructions. What is actually generates is this:

&lt;pre&gt;private static class SiteContainer
{
    public static CallSite&amp;lt;Action&amp;lt;CallSite, object, int, int&amp;gt;&amp;gt; Site;
}

public void DynamicCall(dynamic d, int i)
{
    if (SiteContainer.Site == null)
    {
        SiteContainer.Site = CallSite&amp;lt;Action&amp;lt;CallSite, object, int, int&amp;gt;&amp;gt;.Create(
            Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
                CSharpBinderFlags.ResultDiscarded,
                "Func",
                null,
                typeof(Program),
                new CSharpArgumentInfo[] {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.Constant
                            | CSharpArgumentInfoFlags.UseCompileTimeType,
                        null),
                    CSharpArgumentInfo.Create(
                        CSharpArgumentInfoFlags.UseCompileTimeType,
                        null)
                }));
    }
    
    SiteContainer.Site.Target(SiteContainer.Site, d, 10, i);
}&lt;/pre&gt;

&lt;p&gt;Woah. What on earth is going on here?&lt;/p&gt;

&lt;h4&gt;Creating callsites&lt;/h4&gt;
&lt;p&gt;The core of the DLR is built around the &lt;code&gt;CallSite&lt;/code&gt; and &lt;code&gt;CallSite&amp;lt;T&amp;gt;&lt;/code&gt; types. These types provide the bulk of the infrastructure used to implement C# and VB &lt;code&gt;dynamic&lt;/code&gt;, by providing a sophisticated cache for reflection lookups.&lt;/p&gt;

&lt;p&gt;All the information required to resolve a dynamic call can be split into what is known at compile time, and what is known at runtime. Compile-time information includes the input and output types of the call (as represented by the &lt;code&gt;Action&lt;/code&gt; or &lt;code&gt;Func&lt;/code&gt; type argument to &lt;code&gt;CallSite&amp;lt;T&amp;gt;&lt;/code&gt;), the name of what is being invoked, type arguments, argument names, etc. This information is encapsulated in a &lt;code&gt;CallSiteBinder&lt;/code&gt; that is created the first time a dynamic call is invoked, and stored in the &lt;code&gt;CallSite&lt;/code&gt;, inside a static site container.&lt;/p&gt;

&lt;p&gt;Since this is compiled and invoked from C#, the C# runtime binder, in the &lt;code&gt;Microsoft.CSharp.dll&lt;/code&gt; assembly, is used to create and populate a subclass of &lt;code&gt;CallSiteBinder&lt;/code&gt;. As this particular dynamic call is something that looks like a method invocation, an instance of the &lt;code&gt;CSharpInvokeBinder&lt;/code&gt; type is passed to &lt;code&gt;Create&lt;/code&gt;, using the &lt;code&gt;Binder.InvokeMember&lt;/code&gt; helper method.&lt;/p&gt;

&lt;p&gt;This binder is created using everything it needs to resolve the call at runtime. What exactly is required varies from binder to binder, but the &lt;code&gt;CSharpInvokeBinder&lt;/code&gt; that is used in this example requires information on:
&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;What happens to the return type (in this example, it gets discarded, if there is one)&lt;/li&gt;
&lt;li&gt;The name of the thing being invoked&lt;/li&gt;
&lt;li&gt;Any generic arguments to the method call (in this example, none)&lt;/li&gt;
&lt;li&gt;The type this call is made from (to resolve overloads based on accessibility)&lt;/li&gt;
&lt;li&gt;Information on the arguments (for example, where the value comes from, argument names, whether it's &lt;code&gt;ref&lt;/code&gt; or &lt;code&gt;out&lt;/code&gt;, etc)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, to actually invoke the dynamic call, the actual values used to invoke the callsite each time are passed into the callsite's &lt;code&gt;Target&lt;/code&gt; delegate. This delegate handles resolving the right method to call at runtime, using the information stored in the &lt;code&gt;CallSiteBinder&lt;/code&gt;. How this works is the subject of my next post.&lt;/p&gt;
&lt;small&gt;Cross posted from &lt;a href="http://www.simple-talk.com/community/blogs/simonc"&gt;Simple Talk&lt;/a&gt;.&lt;/small&gt;&lt;img src="http://geekswithblogs.net/simonc/aggbug/150265.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://geekswithblogs.net/simonc/comments/150265.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://geekswithblogs.net/simonc/comments/commentRss/150265.aspx</wfw:commentRss>
        <trackback:ping>http://geekswithblogs.net/simonc/services/trackbacks/150265.aspx</trackback:ping>
    </entry>
</feed>