13

https://github.com/apache/log4net

上記のソースから log4net をコンパイルしていますが、検証に合格しません。

[IL]: エラー: [log4net.dll : log4net.Plugin.RemoteLoggingServerPlugin::Attach][offset 0x00000029] メソッドが表示されません。

コードは大丈夫です:

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);
        ...
    }
}

https://github.com/apache/log4net/blob/trunk/src/Plugin/IPlugin.cs

https://github.com/apache/log4net/blob/trunk/src/Plugin/PluginSkeleton.cs

https://github.com/apache/log4net/blob/trunk/src/Plugin/RemoteLoggingServerPlugin.cs

調査によると、次の呼び出しに失敗しています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()さらに、任意の型で呼び出すと、同じ問題が発生します。

をこれに変更してもAttach()

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

誰かが問題を特定できますか?

4

1 に答える 1

5

この問題は、.NET 4 でレベル 2 透過性が導入されたことに関連しています。(詳細については、 http://msdn.microsoft.com/en-us/library/dd233102.aspxを参照してください。)

メソッドoverride public void Attach(ILoggerRepository repository)に がありませんSecuritySafeCriticalAttribute。属性の追加:

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

IL検証に合格します。(詳細については、http: //msdn.microsoft.com/en-us/library/bb397858.aspxも参照してください。)

更新:検証が失敗する理由 (提供されたリンクの記事を読んだだけではすぐにはわからない可能性があります) をさらに明らかにするために、ここで簡単な説明を示します。

RemotingServices.Marshal[SecuritySafeCritical]属性が適用されています。したがって、透過的なメソッドからのメソッドの呼び出しが許可されると想定されます。ただしRemotingServices.Marshal、タイプのオブジェクトを返し、そのSystem.Runtime.Remoting.ObjRefタイプには[SecurityCritical]属性で注釈が付けられます。
log4net コードが戻り値への参照をローカル変数に格納する場合、コード分析はエラーを検出し、CA2140警告 (「透過的なコードはセキュリティ クリティカルな項目を参照してはなりません」) を発行します。
セキュリティ透過性ルールの下では明らかに、次のサンプルが示すように、透過的メソッドが返されたオブジェクトへの参照を格納していなくても、呼び出されたメソッドがセキュリティ クリティカルな型を返す場合、透過的メソッドはセキュリティ セーフ クリティカル メソッドを呼び出すことはできません。

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
{

} 

このところで。[SecuritySafeCritical]属性を意味のないものにしますRemotingServices.Marshal

于 2012-01-10T22:25:02.367 に答える