UseAfterFree (Windows Driver CodeQL クエリ)

概要

この CodeQL クエリは精度が高く、バグの自動化に役立ちますが、いくつかの制限があるため、UseAfterFree の欠陥のすべてのケースを検出できるわけではありません。

UseAfterFree 欠陥は、割り当てられたメモリ ブロックが解放された後に使用されると発生します (「ダングリング ポインタ」とも呼ばれます)。

このような場合の動作は未定義であり、実際には、メモリの破損、不正な値の使用、または任意のコードの実行などの予期せぬ結果が生じる可能性があります。

推奨

ポインタは解放された直後に NULL に設定します。

次の例では、Status value がゼロでない場合にのみpSomePointerが解放され、 call MethodへのpSomePointer参照を解除する前に、 Statusが再度チェックされます。 残念ながら、StatuspSomePointer への 2 つの参照の間で変更されたため、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 と静的ツールのロゴ テスト」ページを参照してください。