作者:MJ0011 转载请注明

这是Windows XP 从SP0开始存在的一个问题,直到SP2的某一版本(至少在5.1.2600.3093之后)上才修复的这一问题

问题出现在内核函数 ntoskrnl!CmpCheckRecursionAndRecordThreadInfo中

此函数使用了系统函数ExAcquireFastMutex来申请一个快速互斥体,然后在进行一些操作后,使用了ExReleaseFastMutex来释放这个Mutex

ExReleaseFastMutex在一定情况下会调用KeSetEventBoostPriority函数,这个函数在双核下会调用KeAcquireQueuedSpinLockRaiseToSynch函数提升到同步级别,而在单核下则调用KeRaiseIrqlToDpcLevel提升到DPC Level,接着会去操作FastMutex的相关结构内容(DISPATCH_HEADER) ,此时,如果pFastMutex指向的是一个分页内存,将导致BSOD

作者:MJ0011 转载请注明

CmpCheckRecursionAndRecordThreadInfo实际上会在CmpCallCallbacks时调用,是Cm回调机制为了防止递归而加入的一种机制

这个问题将发生在第三方驱动调用系统函数 CmRegisterCallback时发生,该函数作为一种WINDOWS提供的标准安全的注册表监视方式,有众多安全软件在使用(例如, bitfender 2008,2009等),在SP0~SP1或SP2非全补丁的系统上,用户将面临蓝屏风险

CmRegisterCallback将申请一个CM_CALLBACK_CONTEXT_BLOCK的上下文结构的分页内存,其中FastMutex就作为一个结构体包含在这个上下文结构中。

实际这个问题的发生几率并不是特别的高,原因在于CmpCheckRecursionAndRecordThreadInfo在ReleaseMutex之前没多久刚调用过ExAcquireFastMutex,内存在此时仍是换入的,只有在Acquire之后, 提升IRQL 之前,发生了换出,才会触发此问题。但CmCallback本身的触发率很高,因此仍是一个较严重的问题

SP2的全补丁和SP3已经修补了这个问题,微软修改了CM_CALLBACK_CONTEXT_BLOCK的结构,将原本包含在此结构中的FAST_MUTEX结构体,使用一块非分页内存单独存放,而将该结构体的指针存放在CM_CALLBACK_CONTEXT_BLOCK结构中

此问题在微软的KB知识库中有包含:http://support.microsoft.com/kb/936456/zh-cn

但这个网页只提供了给SP2用户的临时补丁