另外一个所涉及的区域就是通过紊乱条件而潜在被利用的安全漏洞。这可能会出现几种方式,下面的子标题概述了开发者必须要避免的一些主要缺陷。
Dispose 方法中的紊乱条件
如果一个类的 Dispose 方法(关于更多信息,请参考:[废物回收])不是同步的,那么 Dispose 中的清理代码就有可能被多次运行,如下范例所示。
void Dispose() { if( myObj != null ) { Cleanup(myObj); myObj = null; } }
因为这个 Dispose 实现并不是同步的,因此 Cleanup 通过第一个线程而被调用然后在第二个线程开始之前会把 myObj 设置成 null。而不管这是否是对于在 Cleanup 代码运行的时候发生了什么事情而产生依赖的安全关系。非同步 Dispose 实现的一个主要的问题中就包括了对于资源句柄的使用。另外,不适当的处理还能够导致错误的句柄被使用,从而经常会导致出现安全方面的弱点。
构造器中的紊乱条件
在有些应用程序中,其他线程会有可能在它们的类构造器完全被运行之前对类的成员进行访问。你应该回顾所有的类构造器来确保在出现这种情况的时候没有安全问题,或者同步线程,如果有必要的话。
已缓存对象的紊乱条件
缓存安全信息的代码或者使用代码访问安全的 Assert 操作对于紊乱条件来说同样可能是易受攻击的,如果类的其他部分没有适当地被同步化,如下列范例所示。
void SomeSecureFunction() { if(SomeDemandPasses()) { fCallersOk = true; DoOtherWork(); fCallersOk = false(); } } void DoOtherWork() { if( fCallersOK ) { DoSomethingTrusted(); } else { DemandSomething(); DoSomethingTrusted(); } }
如果对于 DoOtherWork 的其他路径能够从拥有相同对象的其他线程中被调用,那么一个不被信任的调用者就能够避免通过一个请求。
如果你的代码会缓存安全信息,那么就需要确保你回顾了这个弱点。
最终清理器中的紊乱条件
紊乱条件同样能够出现在一个引用静态资源或者未被管理的资源并且在它的最终清理器中对这些资源进行释放的对象中。如果多个对象共享了一个在类的最终清理器中被操作的资源,那么这个对象就必须同步对于该资源的所有访问。