NN_*_*NN_ 13 .net c# log4net open-source peverify
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);
...
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
但这里没有什么关键.此外RemotingServices.Marshal(),任何类型的呼叫都会导致同样的问题:
即使我改变了Attach()这个:
override public void Attach(ILoggerRepository repository)
{
RemotingServices.Marshal(null, null, typeof(int));
}
Run Code Online (Sandbox Code Playgroud)
有人能发现问题是什么吗?
问题与引入.NET 4 Level 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)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
将使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
{
}
Run Code Online (Sandbox Code Playgroud)
这顺便说一下.使[SecuritySafeCritical]属性变得RemotingServices.Marshal毫无意义.
| 归档时间: |
|
| 查看次数: |
1035 次 |
| 最近记录: |