Freigeben über


UseAfterFree (CodeQL-Abfrage für Windows-Treiber)

Übersicht

Diese CodeQL-Abfrage hat eine hohe Präzision, die bei der Fehlerautomatisierung hilft, hat aber einige Einschränkungen und ist daher nicht in der Lage, alle Fälle von UseAfterFree-Fehlern zu erkennen.

Ein UseAfterFree-Fehler tritt auf, wenn ein zugewiesener Speicherblock verwendet wird, nachdem er freigegeben wurde (auch als "Dangling Pointer" bekannt).

Das Verhalten in solchen Fällen ist undefiniert und kann in der Praxis unbeabsichtigte Folgen haben, einschließlich Speicherbeschädigung, Verwendung falscher Werte oder Ausführung von beliebigem Code.

Empfehlung

Setzen von Zeigern auf NULL unmittelbar nachdem sie freigegeben wurden.

Beispiel

Im folgenden Beispiel wird pSomePointer nur freigegeben, wenn der Wert von Status nicht Null war, und bevor pSomePointer dereferenziert wird, um Method aufzurufen, wird Status erneut überprüft. Leider wurde Status zwischen den beiden Verweisen auf pSomePointer geändert, was die Möglichkeit zulässt, dass der Aufruf von pSomePointer->Method() über einen zuvor freigegebenen Zeiger erfolgt.

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

Im korrigierten Beispiel wird pSomePointer sofort nach dem Freigeben auf NULL gesetzt, und die Bedingung zur Überprüfung, ob es sicher ist, pSomePointer->Method() aufzurufen, prüft diese zusätzliche Bedingung, um den möglichen Fehler zu verhindern.

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

Zusätzliche Details

Diese Abfrage kann im Microsoft GitHub CodeQL Repository gefunden werden. Auf der Seite CodeQL und der Seite Static Tools Logo Test finden Sie Einzelheiten darüber, wie Windows-Treiber-Entwickler CodeQL herunterladen und ausführen können.