CLR 中代码访问安全检测实现原理(2)
以下内容为程序代码:
public void CodeAccessPermission.Demand()
{
CodeAccessSecurityEngine engine = SecurityManager.GetCodeAccessSecurityEngine();
if ((engine != null) && !this.IsSubsetOf(null))
{
StackCrawlMark mark = StackCrawlMark.LookForMyCallersCaller;
engine.Check(this, ref mark);
}
}
可以看到 CodeAccessPermission.Demand 方法,实际上是将验证操作转发给安全管理器 SecurityManager 的代码访问安全引擎 CodeAccessSecurityEngine 类型的 Check 方法完成的。
以下内容为程序代码:
internal class CodeAccessSecurityEngine
{
internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
{
if (!PreCheck(cap, null, 1, ref stackMark, PermissionType.DefaultFlag))
{
Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
}
}
internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark, PermissionType permType)
{
int num1 = 0;
if (CodeAccessSecurityEngine.GetResult(permType, out num1))
{
return;
}
if (this.PreCheck(cap, null, 1, ref stackMark, permType))
{
CodeAccessSecurityEngine.SetResult(permType, num1);
return;
}
this.Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
}
[MethodImpl(MethodImplOptions.InternalCall)]
private void Check(PermissionToken permToken, CodeAccessPermission demand, ref StackCrawlMark stackMark, int checkFrames, int unrestrictedOverride);
}
CodeAccessSecurityEngine 内部类的 Check 方法,将最终调用通过 Unmanaged 代码实现的内部方法进行安全检测。rotor 中的 COMCodeAccessSecurityEngine 类型 (ComCodeAccessSecurityEngine.cpp) 实现了这个检测逻辑。
COMCodeAccessSecurityEngine::Check 函数 (ComCodeAccessSecurityEngine.cpp:683) 通过调用 COMCodeAccessSecurityEngine::CheckInternal 函数 (ComCodeAccessSecurityEngine.cpp:697) 填充一个堆栈遍历请求结构 CasCheckWalkData 的内容,最终将请求转发给 StandardCodeAccessCheck 函数 (ComCodeAccessSecurityEngine.cpp:563) 完成检测。此结构的指针将作为堆栈遍历回调函数的参数传递给回调函数进行实际权限验证,而 StandardCodeAccessCheck 只是负责调用全局堆栈遍历支持 StackWalkFunctions 函数(StackWalk.cpp:512),以 CodeAccessCheckStackWalkCB 函数 (ComCodeAccessSecurityEngine.cpp:449) 为回调函数,以 CheckInternal 函数填充的 CasCheckWalkData 结构为参数,通过现成的堆栈遍历支持 Thread::StackWalkFrames 完成堆栈遍历。
通过堆栈遍历实现代码访问安全检测调用流程如下:
以下为引用:
CodeAccessSecurityEngine::Check 内部调用定义,由下面的函数实现
COMCodeAccessSecurityEngine::Check 转发检测请求 (ComCodeAccessSecurityEngine.cpp:683)
COMCodeAccessSecurityEngine::CheckInternal 填充 CasCheckWalkData 结构 (ComCodeAccessSecurityEngine.cpp:697)
StandardCodeAccessCheck 执行堆栈遍历
Thread::StackWalkFrames 遍历当前线程堆栈
CodeAccessCheckStackWalkCB 检测当前组件权限 (ComCodeAccessSecurityEngine.cpp:449)
因此现在 CAS 检测的问题被分为两个部分:如何遍历调用堆栈;如何检测某个组件是否拥有权限。
Tags:
作者:郁郁小蝎评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论