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