I have an application that uses plugins. The assembly chain looks like this:
App -> A -> B -> A -> B
The assemblies are “App” (the app being run), “A” – a linked in assembly and “B” – an assembly loaded with either Assembly.LoadFile or Assembly.LoadFrom (get the same error with both methods).
It is throwing a security exception trying to LinkDemand unrestricted permissions. The exception happens when A calls B the second time. B is NOT a signed assembly (and therefore I gather from what I’ve read not a strong named assembly). I have also tried putting the [assembly: AllowPartiallyTrustedCallers] attribute in the attribute.cs file for B (and tried putting it on all assemblies). I have even tried putting a permission assert for unrestricted permissions, though from what I’ve read that should have no effect on a LinkDemand.
I am aware that the assembly has reduced permissions (guessing this has something to do with loading it via Assembly). However, everything I’ve read seems to indicate that LinkDemand only checks the calling permissions, so I’m not sure why it would fail the second time instead of the first.
I am confused because: a. why doesn’t it fail the first time, b. why does this happen at all (not using a strong named assembly afaik), and c. why doesn’t adding the APTC attribute fix things.
Just to be clear, I have no security demand attributes on any methods in any of the assemblies (that includes no LinkDemands). I do have some permission asserts in assembly A but I don’t see how that could affect anything.
[System.Security.SecurityException] {"Request failed."} System.Security.SecurityException
Action LinkDemand System.Security.Permissions.SecurityAction
Demanded {<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true"/> } object {System.Security.PermissionSet}
DenySetInstance null object
FailedAssemblyInfo {B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null} System.Reflection.AssemblyName
FirstPermissionThatFailed null System.Security.IPermission
GrantedSet "<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\">\r\n<IPermission class=\"System.Security.Permissions.FileDialogPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAccess=\"Open\"/>\r\n<IPermission class=\"System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAllowed=\"ApplicationIsolationByUser\"\r\nUserQuota=\"512000\"/>\r\n<IPermission class=\"System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nFlags=\"Execution\"/>\r\n<IPermission class=\"System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nWindow=\"SafeTopLevelWindows\"\r\nClipboard=\"OwnClipboard\"/>\r\n<IPermission class=\"System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nUrl=\"file:///Z:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B.dll\"/>\r\n<IPermission class=\"System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nZone=\"Internet\"/>\r\n<IPermission class=\"System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\"\r\nversion=\"1\"\r\nLevel=\"SafePrinting\"/>\r\n</PermissionSet>\r\n" string
Method null System.Reflection.MethodInfo
PermissionState "<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\"\r\nUnrestricted=\"true\"/>\r\n" string
PermissionType {Name = "PermissionSet" FullName = "System.Security.PermissionSet"} System.Type {System.RuntimeType}
PermitOnlySetInstance null object
RefusedSet "" string
Url "file:///Z:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B.dll" string
Zone Internet System.Security.SecurityZone
As suggested by Hans Passant, this appears to have something to do with the security zone being internet. I have since tried the following caspol commands to no avail:
caspol -m -ag 1.2 -url file://z:/* FullTrust
caspol -m -ag 1.2 -url file://\\sam-crazycasta.dyndns.org/crazycasta/* FullTrust
caspol -m -ag 1.3 -url file://z:/* FullTrust
caspol -m -ag 1.3 -url file://\\sam-crazycasta.dyndns.org/crazycasta/* FullTrust
However, copying files local does work. I would like a general solution that allows me to run from network drives and the like. Preferably something I can do from within the program so the user doesn’t need to know anything’s wrong.
Edit 1: I grabbed some code from MSDN to print out policies, and this is what I get, looks to me like FullTrust should be getting granted (the last line is the problem exception):
Policy Level Enterprise:
FullTrust
LocalIntranet
Internet
SkipVerification
Execution
Nothing
Everything
Policy Level Machine:
Nothing
FullTrust
LocalIntranet
Internet
SkipVerification
Execution
Everything
Policy Level User:
FullTrust
LocalIntranet
Internet
SkipVerification
Execution
Nothing
Everything
A first chance exception of type 'System.Security.SecurityException' occurred in mscorlib.dll
This print out is exactly the same whether run from the network where it fails, or from the hard drive where it works.
I also tried adding the following function and calling it before the call that fails:
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Unrestricted = true)]
public void dummy() {}
Since it’s link demanding unrestricted permissions, I don’t see why this function works and the other does not.
I was trying to kill a process in assembly B. This is only a partial answer. I am still confused because the debugger pointed at the line in assembly A that called assembly B instead of the line in assembly B where I tried to kill the process. Here is some code that demonstrates the problem, if someone can tell me how I’m supposed to know the exception is coming from assembly B I’d accept that as an answer.
Assembly A:
Assembly B:
App: