编译时log4net的未通过验证 [英] log4net doesn't pass verification when compiling

查看:219
本文介绍了编译时log4net的未通过验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

https://github.com/apache/log4net

我编译log4net的从源之上,但它并没有通过验证

I am compiling log4net from the source above, but it doesn't pass verification:

[IL]:错误:[log4net.dll:log4net.Plugin.RemoteLoggingServerPlugin ::附加] [偏移0x00000029]的方法是不可见的。

[IL]: Error: [log4net.dll : log4net.Plugin.RemoteLoggingServerPlugin::Attach][offset 0x00000029] Method is not visible.

code是确定:

public interface ILoggerRepository
{
    ...
}

public interface IPlugin
{
    void Attach(ILoggerRepository repository);
}

public abstract class PluginSkeleton : IPlugin
{
    public virtual void Attach(ILoggerRepository repository) { }
}

public class RemoteLoggingServerPlugin : PluginSkeleton
{
    override public void Attach(ILoggerRepository repository)
    {
        base.Attach(repository);
        ...
    }
}

<一个href="https://github.com/apache/log4net/blob/trunk/src/Plugin/IPlugin.cs">https://github.com/apache/log4net/blob/trunk/src/Plugin/IPlugin.cs

<一个href="https://github.com/apache/log4net/blob/trunk/src/Plugin/PluginSkeleton.cs">https://github.com/apache/log4net/blob/trunk/src/Plugin/PluginSkeleton.cs

<一个href="https://github.com/apache/log4net/blob/trunk/src/Plugin/RemoteLoggingServerPlugin.cs">https://github.com/apache/log4net/blob/trunk/src/Plugin/RemoteLoggingServerPlugin.cs

调查表明,在调用失败 RemotingServices.Marshal()

Investigation shows that it fails in calling RemotingServices.Marshal():

override public void Attach(ILoggerRepository repository)
{
    base.Attach(repository);

    // Create the sink and marshal it
    m_sink = new RemoteLoggingSinkImpl(repository);

    try
    {
         **RemotingServices.Marshal(m_sink, m_sinkUri, typeof(IRemoteLoggingSink));**
    }
    catch(Exception ex)
    {
        LogLog.Error(declaringType, "Failed to Marshal remoting sink", ex);
    }
}

但并没有什么重要的位置。此外调用 RemotingServices.Marshal()与任何类型导致了同样的问题:

But there is nothing crucial here. Moreover calling RemotingServices.Marshal() with any type leads to the same problems:

即使我修改附加()来这样的:

override public void Attach(ILoggerRepository repository)
{
    RemotingServices.Marshal(null, null, typeof(int));
}

有人能看出什么问题?

Can someone spot what is the problem?

推荐答案

这个问题涉及到与.NET 4中2级透明度介绍的事实。 (见 http://msdn.microsoft.com/en-us/library/dd233102的.aspx 获取详细信息。)

The problem is related to the fact that with .NET 4 Level 2 transparency was introduced. (See http://msdn.microsoft.com/en-us/library/dd233102.aspx for details.)

方法覆盖公共无效连接(ILoggerRepository库)是缺少 SecuritySafeCriticalAttribute 。添加属性:

The method override public void Attach(ILoggerRepository repository) is lacking the SecuritySafeCriticalAttribute. Adding the attribute:

#if NET_4_0
    [System.Security.SecuritySafeCritical]
#endif
    override public void Attach(ILoggerRepository repository)
    {
        // ...
    }

会使IL验证传递。 (另请参阅: http://msdn.microsoft.com/en-us/library /bb397858.aspx 了解更多信息。)

更新::要解释为什么验证失败一些更多的光线(这可能不会立即通过阅读所提供的链接中的文章全部清除)这里是一个简短的说明

Update: To shed some more light on why verification fails (which might not be immediately clear by just reading the articles in the links provided) here is a short explanation.

RemotingServices.Marshal [SecuritySafeCritical] 属性的应用。因此,人们会认为呼叫从一个透明的方法,该方法将被允许。然而 RemotingServices.Marshal 返回类型的对象 System.Runtime.Remoting.ObjRef 和上述类型的注解与 [SecurityCritical] 属性。
如果log4net的code将存储的引用,返回的值在一个局部变量,code分析会检测到错误并发出的 CA2140 警告(透明code不能引用安全的关键项目)。
现在显然是在安全透明的规则,一个透明的方法可能不叫安全可靠关键的方法,如果被调用的方法返回一个安全关键型即使透明的方法不存储引用返回的对象如下面的示例所示:

RemotingServices.Marshal has the [SecuritySafeCritical] attribute applied. So one would assume that calling the method from a transparent method would be allowed. However RemotingServices.Marshal returns an object of type System.Runtime.Remoting.ObjRef and said type is annotated with the [SecurityCritical] attribute.
If the log4net code would store a reference to the returned value in a local variable, Code Analysis would detect the error and issue a CA2140 warning ("Transparent code must not reference security critical items").
Now apparently under the security transparency rules, a transparent method may not call a security safe-critical method if the called method returns a security critical type even if the transparent method does not store a reference to the returned object as the following sample demonstrates:

public class TransparencyRulesDemo
{
    [SecuritySafeCritical]
    public void SafeGetCritical()
    {
        GetCritical();
    }

    public void TransparentGetCritical()
    {
        // Below line will trigger a CA2140 warning if uncommented...
        // var critical = GetCritical();

        // ...the following line on the other hand will not produce any warning
        // but will lead to IL verification errors and MethodAccessExceptions if
        // called from transparent code.
        GetCritical();
    }

    [SecuritySafeCritical]
    public Critical GetCritical()
    {
        return new Critical();
    }
}

[SecurityCritical]
public class Critical
{

} 

这BTW。使得对 RemotingServices.Marshal 一种毫无意义的 [SecuritySafeCritical] 属性。

This btw. makes the [SecuritySafeCritical] attribute on RemotingServices.Marshal kind of pointless.

这篇关于编译时log4net的未通过验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆