Partager via


UseAfterFree (requête CodeQL du pilote Windows)

Vue d’ensemble

Cette requête CodeQL a une grande précision, ce qui aide à l’automatisation des bugs, mais présente certaines limitations et ne pourra donc pas détecter tous les cas de défauts de type UseAfterFree.

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.