Probable UseAfterFree (requête CodeQL du pilote Windows)
Vue d’ensemble
Cette requête CodeQL une précision plus faible que la requête CodeQL UseAfterFree de haute précision. Elle détecte certains scénarios supplémentaires, mais présente également un taux plus élevé de faux positifs.
Un défaut UseAfterFree se produit lorsqu’un bloc de mémoire alloué est utilisé après avoir été libéré (également connu sous le nom de « pointeur suspendu »).
Le comportement dans de tels cas est indéfini et peut en pratique avoir des conséquences involontaires, y compris la corruption de mémoire, l’utilisation de valeurs incorrectes ou l’exécution de code arbitraire.
Recommandation
Définissez les pointeurs sur NULL immédiatement après les avoir libérés.
Exemple
Dans l’exemple suivant, pSomePointer
n’est libéré que si la valeur de Status
n’était pas nulle, et avant de déréférencer pSomePointer
pour appeler Method
, Status
est vérifié à nouveau. Malheureusement, Status
a été modifié entre les deux références à pSomePointer
, ce qui permet la possibilité que l’appel à pSomePointer->Method()
soit effectué sur un pointeur précédemment libéré.
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();
}
Dans l’exemple corrigé, pSomePointer
est défini sur NULL
immédiatement après avoir été libéré, et la condition pour vérifier s’il est sûr d’appeler pSomePointer->Method()
tient compte de cette condition supplémentaire pour éviter le bug possible.
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();
}
Informations supplémentaires
Cette requête peut être trouvée dans le référentiel Microsoft GitHub CodeQL. Consultez la page CodeQL et le test du logo des outils statiques pour plus de détails sur la manière dont les développeurs de pilotes Windows peuvent télécharger et exécuter CodeQL.