UseAfterFree(Windows 驱动程序 CodeQL 查询)
概述
该 CodeQL 查询精度很高,有助于错误自动化,但也有一些局限性,因此无法检测到 UseAfterFree 缺陷的所有情况。
UseAfterFree 缺陷发生在已分配的内存块被释放后又被使用时(也称为“悬空指针”)。
这种情况下的行为是未定义的,在实践中可能会产生意想不到的后果,包括内存损坏、使用不正确的值或执行任意代码。
建议
释放指针后,立即将指针设置为 NULL。
示例
在下面的示例中,只有当 Status
的值不为零时,才会释放 pSomePointer
,在取消引用 pSomePointer
以调用 Method
之前,会再次检查 Status
。 遗憾的是,Status
在两次引用 pSomePointer
之间发生了变化,这使得对 pSomePointer->Method()
的调用有可能是在一个先前释放的指针上进行的。
NTSTATUS Status = x();
if (Status != 0)
{
// Release pSomePointer if the call to x() failed
ExFreePool(pSomePointer);
}
Status = y();
if (Status == 0)
{
// Because Status may no longer be the same value than it was before the pointer was released,
// this code may be using pSomePointer after it was freed, potentially executing arbitrary code.
Status = pSomePointer->Method();
}
在更正后的示例中,pSomePointer
被释放后立即被设置为 NULL
,而检查调用 pSomePointer->Method()
是否安全的条件会检查这一附加条件,以防止可能出现的错误。
NTSTATUS Status = x();
if (Status != 0)
{
// Release pSomePointer if the call to x() failed
ExFreePool(pSomePointer);
// Setting pSomePointer to NULL after being freed
pSomePointer = NULL;
}
Status = y();
// If pSomePointer was freed above, its value must have been set to NULL
if (Status == 0 && pSomePointer != NULL)
{
Status = pSomePointer->Method();
}
其他详细信息
该查询可在 Microsoft GitHub CodeQL 代码库中找到。 有关 Windows 驱动程序开发人员如何下载和运行 CodeQL 的详细信息,请参见 CodeQL 和静态工具徽标测试页面。