LinkDemands and InheritenceDemands Occur at JIT Time

We previously saw that the SkipVerification demand for calling a method with unverifiable code occurs at JIT time rather than at runtime.  Two other types of demands also occur at JIT time, LinkDemands and InheritenceDemands.  An InheritenceDemand will occur when the method of the derived class is being JITed, while a LinkDemand occurs when the method which calls the method containing the LinkDemand is being JITed.  For instance, if method A calls method B, which has a LinkDemand for FullTrust, the demand occurs when A is JITed.  If method C overrides a method in class D which is protected with an InheritenceDemand, the demand occurs when C is JITed.

This has some interesting consequences.  Since the basic unit of JIT compilation is the method, you cannot have a single method which checks the permission set its running with, and then conditionally calls a method protected by a LinkDemand if if would satisfy that demand.  Instead, it would have to check it’s permissions and if it had enough call another method which simply turned around and called the method with the LinkDemand.  Similarly, you cannot do a try … catch(SecurityException) around a method protected by a LinkDemand.

I recently was asked a question about a program that stopped working when it was moved to a file share.  The author of the application attempted handle this gracefully by displaying an error message to his users indicating that they need to increase the trust of the application.  However, even that code didn’t help — it seemed as though the application’s Main method never even got to execute.

It turns out that Main created a Mutex object, and the Mutex constructor contains a LinkDemand for UnmanagedCode.  Now that we know that this demand will occur at JIT time, the observed behavior seems understandable.  When the JIT attempted to compile Main, it found a call to a method that had a LinkDemand for UnmanagedCode, and so checked the permission set of the assembly containing Main.  It then found that this assembly did not have UnmanagedCode Permission, so it threw a SecurityException rather than compiling the method.  This prevented the author’s attempt to fail gracefully from ever running, and the application died with an unhandled exception.  In fact, since this occurred while JITing Main, there actually wasn’t even a call stack yet, so the exception message wasn’t even particularly helpful in tracking down the problem.

One way to fix this is to have Main first do the check for FullTrust, then call another method which does the work that used to occur in the original Main method.  This way, the application’s entry point is allowed to JIT, and it can provide a useful diagnostic message to the users in the case that they need to provide extra trust for the code.

Comments (5)

  1. Sam says:

    With your suggested fix, surely the second method will fail to compile before Main is run and so the app will fail in the same way?

  2. shawnfa says:

    A method is only compiled when it is called for the first time. In the suggested fix, Main does it’s check before the method call is done, and therefore the JIT never causes the SecurityException to be thrown.


  3. Eric Cosky says:

    Great tip. The follow code makes my program pop a dialog when it’s run from a shared drive. You have to set the app’s entry point to ProgramWrapper.Main instead of default as it’s usually set is the only catch.


    static class ProgramWrapper



    static void Main(string[] args)






    catch (System.Security.SecurityException)


    MessageBox.Show("This application must be run from a secure location, such as a local disk.");




    static class Program


    /// <summary>

    /// The main entry point for the application.

    /// </summary>


    public static void Main(string[] args)




    Application.Run(new BrowserSelectorForm(args));




  4. Yisman says:


    i have a snippet of code to do a backup of my sqlserver db. it goes like this:

    Imports Microsoft.SqlServer.Management

    Public Shared Sub Backup()

           Dim sqlCon = New SqlConnection(ConfigurationManager.ConnectionStrings("Main").ConnectionString)

           Dim conn As New ServerConnection(sqlCon)

    End Sub

    the method which calls this "Backup" method fails at runtime with a security exception "That assembly does not allow partially trusted callers."

    looking at the exception details i see that

    a) the action was System.Security.Permissions.SecurityAction.LinkDemand

    b) the firstpermiissionthatfailed was Request for the permission of type ‘System.Security.Permissions.SecurityPermission, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089’ failed.

    if i understand correctly, these permission can somehow be added to the web_mediumtrust.config file, so as to allow the code to run.

    problem is i cant for the life of me figure out what am i supposed to add. here is the IPermission line of my medium config if it helps:

     <IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration"/>

    what can i do?

    thank you

  5. shawnfa says:

    "That assembly does not allow partially trusted callers" means that your assembly containing the Backup method needs to be marked with the AllowPartiallyTrustedCallers attribute – that should solve the problem for you.