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 和静态工具徽标测试页面。