I am trying to load an Assembly into a restricted AppDomain. If I do not specify any restrictions, the Assembly will load correctly:
var permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
AppDomain targetAppDomain = AppDomain.CreateDomain("LockedDomain" + Guid.NewGuid().ToString("N"),null,domainSetup,permissionSet,null);
var instance = (IRemoteFilterClass) targetAppDomain.CreateInstanceFromAndUnwrap(tempAssemblyPath, "CompiledCode.CompiledClass");
Howevere I want to lock down the created AppDomain as completely as possible, i.e. only give permissions which are absolutely necessary. If I specify a PermissionSet to restrict Permissions, the Assembly fails to load:
var permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.None);
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, tempAssemblyPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, tempAssemblyPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, Assembly.GetExecutingAssembly().Location));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, Assembly.GetExecutingAssembly().Location));
permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted)); //Not sure if this is necessary, but does not work anyway
AppDomain targetAppDomain = AppDomain.CreateDomain("LockedDomain" + Guid.NewGuid().ToString("N"),null,domainSetup,permissionSet,null);
var instance = (IRemoteFilterClass) targetAppDomain.CreateInstanceFromAndUnwrap(tempAssemblyPath, "CompiledCode.CompiledClass");
The following exception is thrown:
System.IO.FileLoadException: Could not load file or assembly '5e1a72b7c5584f7c92c18ea9b221222f, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418) ---> System.Security.Policy.PolicyException: Execution permission cannot be acquired.
at System.Security.CodeAccessSecurityEngine.ResolveGrantSet(Evidence evidence, Int32& specialFlags, Boolean checkExecutionPermission)
--- End of inner exception stack trace ---
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile, Evidence securityEvidence)
at System.Activator.CreateInstanceFromInternal(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo)
at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName)
at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
It seems as if there are still Permissions missing, but I have no idea which ones are missing.
It is necessary to add a SecurityPermission
with the SecurityPermissionFlag.Execution
set.
Here is the working code:
var permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.None);
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, tempAssemblyPath));
permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, tempAssemblyPath));
//The following line fixed the code
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
AppDomain targetAppDomain = AppDomain.CreateDomain("LockedDomain" + Guid.NewGuid().ToString("N"),null,domainSetup,permissionSet,null);
var instance = (IRemoteFilterClass) targetAppDomain.CreateInstanceFromAndUnwrap(tempAssemblyPath, "CompiledCode.CompiledClass");
User contributions licensed under CC BY-SA 3.0