Udostępnij przez


Zapytanie CodeQL dla sterownika systemu Windows: UseAfterFree

Przegląd

To zapytanie CodeQL ma wysoką precyzję, która pomaga w automatyzacji błędów, ale ma pewne ograniczenia i dlatego nie będzie w stanie wykryć wszystkich przypadków wad UseAfterFree.

Usterka UseAfterFree występuje, gdy przydzielony blok pamięci jest używany po jego uwolnieniu (nazywany również "zwisającym wskaźnikiem").

Zachowanie w takich przypadkach jest niezdefiniowane, a w praktyce mogą mieć niezamierzone konsekwencje, w tym uszkodzenie pamięci, użycie nieprawidłowych wartości lub dowolne wykonanie kodu.

Rekomendacja

Ustaw wskaźniki na NULL natychmiast po ich uwolnieniu.

Przykład

W poniższym przykładzie, pSomePointer jest zwalniany tylko wtedy, gdy wartość Status nie była równa zeru, a przed wyłuszczeniem pSomePointer, aby wywołać metodę Method, Status jest ponownie sprawdzane. Niestety doszło do zmiany pomiędzy dwoma odniesieniami do Status, co może doprowadzić do sytuacji, że wywołanie pSomePointer jest wykonywane przez wcześniej zwolniony wskaźnik.

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();
}

W poprawionym przykładzie pSomePointer jest ustawiany na NULL natychmiast po uwolnieniu, a warunek sprawdzający, czy jest bezpiecznie wywołać pSomePointer->Method(), sprawdza ten dodatkowy warunek, aby zapobiec możliwej usterce.

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();
}

Dodatkowe szczegóły

To zapytanie można znaleźć w repozytorium Microsoft GitHub CodeQL. Zobacz stronę CodeQL i Static Tools Logo Test, aby uzyskać szczegółowe informacje na temat pobierania i uruchamiania CodeQL przez programistów sterowników systemu Windows.