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.