考えられる UseAfterFree (Windows Driver CodeQL クエリ)
概要
この CodeQL クエリは、高精度の UseAfterFree CodeQLクエリよりも精度が低くなります。 いくつかの追加シナリオも検出しますが、誤検知率も高くなります。
UseAfterFree 欠陥は、割り当てられたメモリ ブロックが解放された後に使用されると発生します (「ダングリング ポインタ」とも呼ばれます)。
このような場合の動作は未定義であり、実際には、メモリの破損、不正な値の使用、または任意のコードの実行などの予期せぬ結果が生じる可能性があります。
推奨
ポインタは解放された直後に NULL に設定します。
例
次の例では、Status
value がゼロでない場合にのみpSomePointer
が解放され、 call Method
へのpSomePointer
参照を解除する前に、 Status
が再度チェックされます。 残念ながら、Status
は pSomePointer
への 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 と静的ツールのロゴ テスト」ページを参照してください。