NHibernate with logging throws a Security Exception under Medium Trust

I am using NHibernate 3.2.0 under Medium Trust and all was going well until I turned on logging to try and trace a SQL error. It seems that when you set the log4net logging level to INFO that under a medium trust NHibernate throws a Security Exception.

Here is the Security Exception.

[SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]     System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) +0     System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark) +31     System.Security.CodeAccessPermission.Demand() +46     System.Reflection.RuntimeAssembly.VerifyCodeBaseDiscovery(String codeBase) +118     System.Reflection.RuntimeAssembly.GetName(Boolean copiedName) +69     System.Reflection.Assembly.GetName() +12     NHibernate.Cfg.Environment.get_Version() +114     NHibernate.Cfg.Environment..cctor() +130  

 

You can see from the stack trace exactly where the error was occurring, its quite clear. In the NHibernate source the static constructor for the Environment you can see that the NHibernate Version is logged, I was picking that is where the the error was occurring.

 

        static Environment() 
        { 
            // Computing the version string is a bit expensive, so do it only if logging is enabled. 
            if (log.IsInfoEnabled) 
            { 
                log.Info("NHibernate " + Version); 
            } 
 
            GlobalProperties = new Dictionarystring, string>(); 
            GlobalProperties[PropertyUseReflectionOptimizer] = bool.TrueString; 
            LoadGlobalPropertiesFromAppConfig(); 
            VerifyProperties(GlobalProperties); 
 
            BytecodeProviderInstance = BuildBytecodeProvider(GlobalProperties); 
            EnableReflectionOptimizer = PropertiesHelper.GetBoolean(PropertyUseReflectionOptimizer, GlobalProperties); 
 
            if (EnableReflectionOptimizer) 
            { 
                log.Info("Using reflection optimizer"); 
            } 
        } 

 

So what is wrong with accessing the Version property?

  

        public static string Version 
        { 
            get 
            { 
                if (cachedVersion == null) 
                { 
                    Assembly thisAssembly = Assembly.GetExecutingAssembly(); 
                    var attrs = 
                        (AssemblyInformationalVersionAttribute[]) 
                        thisAssembly.GetCustomAttributes(typeof (AssemblyInformationalVersionAttribute), false); 
 
                    if (attrs != null && attrs.Length > 0) 
                    { 
                        cachedVersion = string.Format("{0} ({1})", thisAssembly.GetName().Version, attrs[0].InformationalVersion); 
                    } 
                    else 
                    { 
                        cachedVersion = thisAssembly.GetName().Version.ToString(); 
                    } 
                } 
                return cachedVersion; 
            } 
        } 

 

So it seemed the Security Exception was being thrown on the call to Assembly.ExecutingAssembly()

After quite a bit of searching Google it turned out Phil Haack had also come across the problem and had written a really good account of what the problem is and the solution.

Rather than compile my custom version of NHibernate version I decided just to debug my NHibernate HQL under under Full Trust and change it back to Medium Trust when I had sorted out my problems.