I've now found the reason for NH-3340 - NHibernate assembly loses the 
AllowPartiallyTrustedCallers attribute after ILMerge 
(https://nhibernate.jira.com/browse/NH-3340). But since this is going to be 
more a question/discussion than a comment for that bug I'll post it here.

So the reason why this attribute is there in NHibernate 3.3.x but is 
missing in 4.0.0 is that the 3.3.x branch still uses some older ILMerge 
version (2.10.526) whereas the master branch uses the latest version 
(2.12.803). Using the old ILMerge for building the master branch solves the 
problem of the missing AllowPartiallyTrustedCallers attribute (but causes 
other problems, more on that later).

Using the .NET Reflector I found the following code in the latest ILMerge:

else if (((node6.Type == SystemTypes.SecurityCriticalAttribute) || 
(node6.Type == SystemTypes.SecurityTransparentAttribute)) || ((node6.Type 
== SystemTypes.AllowPartiallyTrustedCallersAttribute) || 
node6.Type.FullName.Equals("System.Security.SecurityRules")))
            {
                this.WriteToLog("Assembly level attribute '{0}' from 
assembly '{1}' being deleted from target assembly", new object[] { 
node6.Type.FullName, a.Name });
                a.Attributes[num8] = null;
            }

So it seems like all those security attributes are always removed. 
Interestingly the change log of ILMerge 
(http://research.microsoft.com/en-us/people/mbarnett/changehistory.aspx) 
doesn't mention this change. But most likely it was because of the problem 
I'm now getting:

After merging the NHibernate 4.0.0 assembly with the old ILMerge I'm 
getting the following exception when executing a Linq query:
Inheritance security rules violated while overriding member: 
'Remotion.Linq.Utilities.ArgumentTypeException.GetObjectData(System.Runtime.Serialization.SerializationInfo,
 
System.Runtime.Serialization.StreamingContext)'. Security accessibility of 
the overriding method must match the security accessibility of the method 
being overriden.

So re-linq is not setting the correct security attributes for .NET 4.0 
which is understandable since it still targets 3.5. How should this ever 
work without requiring all dependencies to target .NET 4.0 and fixing their 
security attributes?

I'm no .NET security expert but I think the best solution would be to 
rollback to the old ILMerge version and additionally set the [assembly: 
SecurityRules(SecurityRuleSet.Level1)] attribute for the NHibernate 
assembly. That way everything should behave like previously. Completely 
removing ILMerge and falling back to seperate assemlies should also be an 
option, but I don't think that is a good solution. Opinions?

PS: Here is a very good explanation of what AllowPartiallyTrustedCallers 
means in the .NET 4.0 security world: 
http://msdn.microsoft.com/en-us/magazine/ee336023.aspx

Reply via email to