none
Access is denied while loading strong name DLL into Default Domain RRS feed

  • Question

  • Hello, on the target server I am trying to load strong name DLL into default domain and got 'Access is denied' while the same DLL without strong name has loaded and works OK.
    On the development PC all works fine.

    I have tryed to add assembly evidence into CurrentDomain->Evidence, nothing is changed.

    I have tryed to research this and looked at System.Security.Policy.Evidence.FindType(Type t)

    internal object FindType(Type t)
    {
      int num;
      for (num = 0; num < ((this.m_hostList == null) ? 0 : this.m_hostList.Count); num++)
      {
        if (this.m_hostList[num].GetType() == t)
        {
          return this.m_hostList[num];
        }
      }
      for (num = 0; num < ((this.m_assemblyList == null) ? 0 : this.m_assemblyList.Count); num++)
      {
        if (this.m_assemblyList[num].GetType() == t)
        {
          return this.m_hostList[num];
        }
      }
      return null;
    }
     

    I am confused by this fragment:

        if (this.m_assemblyList[num].GetType() == t)
        {
          return this.m_hostList[num];
        }
    

    Is it correct to test assemblyList and then return item from hostList ?

    Anyway I am not sure that this cause access denied.

    Hmm, any ideas?

    WBR,
    Dmitry
     


    Dmitry Shuklin, http://www.shuklin.com
    Wednesday, April 28, 2010 6:48 PM

All replies

  • That doesn't look correct. I will ask our experts on this ...

    -Karel

    Wednesday, April 28, 2010 10:21 PM
    Moderator
  • Thank you for your report. I do not believe that the code snippet you posted would be causing the behavior that you are observing. There is a possibility that you’re encountering a security feature called APTCA. You can try adding the [assembly:AllowPartiallyTrustedCallers] attribute to your strongly named assembly and see if that changes the behavior.

    To do more substantial investigation into the matter, I would need some more information from you. Could you please provide the full error message you’re encountering along with a stack trace? If you’re able to provide a simple repro stripped of any sensitive information, that would help greatly.

    Reid Borsuk

    Thursday, April 29, 2010 4:50 PM
  • Reid, Thank You for the idea!

    I will try to play with [assembly:AllowPartiallyTrustedCallers]

    Now I am having this stack trace:

    Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'd:\users\konkurs10-1\cerebrum\Cerebrum.Typedef.dll' or one of its dependencies. Access is denied.
    File name: 'd:\users\konkurs10-1\cerebrum\Cerebrum.Typedef.dll'
     at System.Reflection.AssemblyName.nGetFileInformation(String s)
     at System.Reflection.AssemblyName.GetAssemblyName(String assemblyFile)
     at SetDomainPolicyInternal(AppDomain pAppDomain)

    SetDomainPolicyInternal is managed function, it is called from unmanaged portion of code.

    WBR,
    Dmitry

    PS: seems that AllowPartiallyTrustedCallers doesn't solve the problem ((


    Dmitry Shuklin, http://www.shuklin.com
    Thursday, April 29, 2010 6:41 PM
  • Still not worked (((

    Seems that current thread does not have sufficient rights to use crypto API to validate StrongNames

    What rights should have unmanaged thread to use Strong Name Assemblies?

    WBR,
    Dmitry

     


    Dmitry Shuklin, http://www.shuklin.com
    Saturday, May 1, 2010 12:33 PM
  •  

    Are you sure 'd:\users\konkurs10-1\cerebrum\Cerebrum.Typedef.dll' is accessible for current user? you may use Process Monitor to find out what happened when your application try to load Cerebrum.Typedef.dll.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, May 3, 2010 7:54 AM
  •  

    Are you sure 'd:\users\konkurs10-1\cerebrum\Cerebrum.Typedef.dll' is accessible for current user? you may use Process Monitor to find out what happened when your application try to load Cerebrum.Typedef.dll.


     

    Yes, I am sure. I have made few different tests. I have made " Cerebrum.Typedef.dll "  with StrongName and without. Also I have made simple test.dll with SN and without. I am tested FW v1.1.4322 and v2.0.50727 Behavior is the same:

    When project does not contain any SN assemblies all works fine.

    Now I am not sure that thread have access to crypto API. Hmm, may it be that FW tryes to check SN consistency and crypto API retruns Access Denied?

    Unfortunatelly I don't have access to target PC directly. For debugging I can use only my self implemented logging.

    WBR,
    Dmitry

     


    Dmitry Shuklin, http://www.shuklin.com
    Thursday, May 6, 2010 6:28 PM
  • Is it an .NET or unmanaged application? could you please post some code snippets that used for loading the managed dll?

    Fuslogvw.exe is good at finding out assembly binding issues, if it is possible, you may use it to get more detail information about this exception.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, May 7, 2010 9:37 AM
  • Is it an .NET or unmanaged application? could you please post some code snippets that used for loading the managed dll?

    Hi Eric,

    It is mixed application. host.EXE file is pure unmanaged. Rest of DLLs are mixed and managed.

    I don't know is it important that I am starting FW runtime in the worker thread, instead of the primary process thread. I am starting thread without specifying security attribute :

    	hThreadHandle = CreateThread( 
    		NULL,			// No security attribute 
    		0,			// Default stack size 
    		(LPTHREAD_START_ROUTINE) WorkerThread, 
    		(LPVOID) &threadSetup,	// Thread parameter 
    		0,			// Not suspended 
    		&dwThreadID);		// Returns thread ID 
    

    CorBindToRuntimeEx is called from worker thread. All .NET code is executed in this thread.
    WorkerThread starts FW runtime by calling CorBindToRuntimeEx:

    	ICorRuntimeHost *pClrHost = NULL;
    	HRESULT hr;
    
    	hr = CoInitialize(NULL);
    
    	hr = CorBindToRuntimeEx(
    		L"v1.1.4322"/*L"v2.0.50727"*//*NULL*/,						
    		L"svr",
    			 STARTUP_CONCURRENT_GC 
    			| STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN 
    			| STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST,
    		CLSID_CorRuntimeHost,
    		IID_ICorRuntimeHost,
    		(PVOID*)&pClrHost);
    
    	pClrHost->Start();
    

    I have tryed to start diferent FW versions, and didn't see any changes.

    I have stub.DLL with mixed unmanaged and managed code. This stub.DLL is written on MC++ in the VS2003 (FW1.1), it is not signed by SN, WorkerThread loads this DLL into host.EXE process by LoadLibrary successfully and calls unmanaged stub.DLL.InitializeRuntime()

    #pragma

     

    unmanaged





    BOOL WINAPI InitializeRuntime() { WriteToLog(GetStdHandle(STD_OUTPUT_HANDLE), "InitializeRuntime entered. \r\n"); return InitializeRuntimeInternal(); }

     InitializeRuntimeInternal() is managed function and resides in the same stub.DLL

    #pragma

     

    managed

     

    BOOL WINAPI InitializeRuntimeInternal()

    {

    System::AppDomain * pCurrentAppDomain = System::AppDomain::CurrentDomain;

    return SetDomainPolicyInternal(pCurrentAppDomain);

    }

     

    BOOL WINAPI SetDomainPolicyInternal(System::AppDomain * pAppDomain)

    {

    System::Console::WriteLine(S"SetDomainPolicyInternal");

    System::Console::WriteLine(System::String::Concat(S" ",

    __typeof(System::Object)->Assembly->Location));

    System::Console::WriteLine(System::String::Concat(S" ", pAppDomain->BaseDirectory));

     

     

    // now grant permissions explicitly for the sandbox

    System::Security::Permissions::PermissionState fullTrustState = System::Security::Permissions::PermissionState::Unrestricted;

    System::Security::PermissionSet *permissionSet=

    new System::Security::PermissionSet(fullTrustState);

    permissionSet->AddPermission(

    new System::Security::Permissions::FileIOPermission(fullTrustState));

    permissionSet->AddPermission(

    new System::Security::Permissions::SecurityPermission(System::Security::Permissions::SecurityPermissionFlag::AllFlags));

    System::Security::Policy::PolicyStatement * fullTrustPolicy =

    new System::Security::Policy::PolicyStatement(permissionSet);//, System::Security::Policy::PolicyStatementAttribute::All );

    System::Security::Policy::CodeGroup *fullTrustCodeGroup =

    new System::Security::Policy::UnionCodeGroup(new System::Security::Policy::AllMembershipCondition(), fullTrustPolicy);

    System::Security::Policy::PolicyLevel * policyLevel = System::Security::Policy::PolicyLevel::CreateAppDomainLevel();

    policyLevel->RootCodeGroup = fullTrustCodeGroup;

     

    System::Byte publicKeyBytes[];

     

    // create Cerebrum.Typedef PublicKeyBlob

    publicKeyBytes =

    new System::Byte[160];

     

    for(int i=0; i<160; i++)

    {

    publicKeyBytes[i] = publicKey[i];

    }

    System::Security::Permissions::StrongNamePublicKeyBlob * keyBlob =

    new System::Security::Permissions::StrongNamePublicKeyBlob(publicKeyBytes);

     

     

    // and create the membership condition

    System::Security::Policy::StrongNameMembershipCondition *mcTypedefDLL =

    new System::Security::Policy::StrongNameMembershipCondition(keyBlob, NULL, NULL); //assemblyName.Name, assemblyName.Version);

    policyLevel->AddFullTrustAssembly(mcTypedefDLL);

    pAppDomain->SetAppDomainPolicy(policyLevel);

     

    System::Version * version;

    version =

    new System::Version(1, 0, 300, 20);

    System::String * dllName = S"Cerebrum.Typedef";

     

    System::String * primaryDirectory = System::IO::Path::GetDirectoryName(

    __typeof( any_type_inside_stub_DLL )->Assembly->Location);

     

    System::Security::Policy::Evidence * domainEvidence = pAppDomain->Evidence;

     

    System::Security::Policy::StrongName * snTypedefDLL =

    new System::Security::Policy::StrongName(keyBlob, dllName, version);

     

    //domainEvidence->AddAssembly(snTypedefDLL);

    domainEvidence->AddHost(snTypedefDLL);

     

     

     

    //System::Console::WriteLine(S"trying to load typedef directly");

     

    //pAppDomain->Load(System::IO::Path::Combine(primaryDirectory, S"Cerebrum.Typedef.dll"));

     

     

    System::Console::WriteLine(S"trying to get typedef name");

    System::Reflection::AssemblyName * assemblyName = System::Reflection::AssemblyName::GetAssemblyName( System::IO::Path::Combine( primaryDirectory, S"Cerebrum.Typedef.dll" ) );

     

     

    System::Console::WriteLine(S"trying to load typedef");

     

    //pAppDomain->Load(assemblyName, domainEvidence);

    pAppDomain->Load(assemblyName);

     

     

     

    //System::Console::WriteLine(S"trying to load test11.dll");

     

    //pAppDomain->Load(System::Reflection::AssemblyName::GetAssemblyName( System::IO::Path::Combine( primaryDirectory, S"test11.dll" ) ) );

     

     

    return TRUE;

    }

    On the development PC all runs OK. On the Web server System::Reflection::AssemblyName::GetAssemblyName fires Access Denied:

    Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'd:\users\konkurs10-1\cerebrum\Cerebrum.Typedef.dll' or one of its dependencies. Access is denied.
    File name: 'd:\users\konkurs10-1\cerebrum\Cerebrum.Typedef.dll'
     at System.Reflection.AssemblyName.nGetFileInformation(String s)
     at System.Reflection.AssemblyName.GetAssemblyName(String assemblyFile)
     at SetDomainPolicyInternal(AppDomain pAppDomain)

    I have tryed to load empty test11.dll (FW 1.1), also tryed test20.dll (FW 2.0) and didn't see any changes.

    In the one experiment I have very interesing behavior. I am signed stub.DLL with SN. stub.DLL loaded into process by LoadLibrary successfully. Then logs indicated that unmanaged InitializeRuntime runned OK . But in the SN stub.DLL managed InitializeRuntimeInternal don't want to run with Access Denied.

    I think that Win32 API loads DLL OK in the all scenarios. Error is occured only when FW tryes to load SN DLL into app domain. When the same DLL is missing SN all goes OK because FW didn't need to call Crypto API to decode RSA.

    I don't know what rights thread must have to run Crypto API. I am not familiar with Crypto API and didn't make any direct test of Crypto API so it is only assumption.

    WBR,
    Dmitry

     


    Dmitry Shuklin, http://www.shuklin.com
    Friday, May 7, 2010 11:25 AM
  • Hello All!

    I have made few additional experiments and reproduced similar error on my dev PC.

    To reproduce error :

    - create ASPNET 2.0 application in its own virtual directory

    - in the file system add NETWORK SERVICE to security of the application file directory , deny Read access.

    In the event viewer I found this error:

    Failed to initialize the AppDomain:/LM/W3SVC/1/Root/test
    
    Exception: System.IO.FileLoadException
    
    Message: Could not load file or assembly 'System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Access is denied.
    
    StackTrace:  at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
      at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
      at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
      at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
      at System.Activator.CreateInstance(String assemblyName, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
      at System.Activator.CreateInstance(String assemblyName, String typeName)
      at System.AppDomain.CreateInstance(String assemblyName, String typeName)
      at System.AppDomain.CreateInstance(String assemblyName, String typeName)
      at System.Web.Hosting.ApplicationManager.CreateAppDomainWithHostingEnvironment(String appId, IApplicationHost appHost, HostingEnvironmentParameters hostingParameters)
      at System.Web.Hosting.ApplicationManager.CreateAppDomainWithHostingEnvironmentAndReportErrors(String appId, IApplicationHost appHost, HostingEnvironmentParameters hostingParameters)
    
    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

    System.Web is Strong Name DLL and file access is not denied to this DLL.

     


    Dmitry Shuklin, http://www.shuklin.com
    Thursday, February 3, 2011 1:23 PM