Partager via


Règle UnSafeAllocatePool (wdm)

La règle UnSafeAllocatePool est une règle de sécurité importante qui vérifie qu’un pilote n’utilise pas de DDIs dépréciés pour allouer de la mémoire.

La règle UnsafeAllocatePool spécifie que le pilote ne doit pas appeler :

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

Cette règle est disponible dans les versions WDK 20236 et ultérieures en préversion.

Mises à jour des pilotes pour les versions de Windows 10, version 2004 et ultérieures

Si vous créez un pilote qui cible Windows 10, version 2004 et ultérieure, utilisez les API de remplacement ExAllocatePool2 et ExAllocatePool3 à la place.

Ancienne API Nouvelle API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

Les nouvelles API n’ont aucune allocation de pool par défaut, afin d’éviter d’éventuels bogues de divulgation de mémoire.

ExAllocatePool/ExAllocatePoolWithTag

// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code
PVOID Allocation = ExAllocatePool2(POOL_FLAG_PAGED, 100, 'abcd');

Les anciennes API d’allocation de pool acceptent un argument POOL_TYPE , mais les nouvelles API d’allocation acceptent un argument POOL_FLAGS . Mettez à jour tout code associé pour utiliser le nouvel argument POOL_FLAGS .

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

La nouvelle fonction retourne désormais null en cas d’échec d’allocation par défaut. Pour que l’allocateur déclenche une exception en cas d’échec, l’indicateur POOL_FLAG_RAISE_ON_FAILURE doit être passé comme indiqué dans ExAllocatePool2.

// Old code
PVOID Allocation = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code
PVOID Allocation = ExAllocatePool2(POOL_FLAG_PAGED | POOL_FLAG_USE_QUOTA, 100, 'abcd');

ExAllocatePoolWithTagPriority

// Old code
PVOID Allocation = ExAllocatePoolWithTagPriority(PagedPool, 100, 'abcd', HighPoolPriority);
RtlZeroMemory(Allocation, 100);

// New code
POOL_EXTENDED_PARAMETER params = {0};
params.Type = PoolExtendedParameterPriority;
params.Priority = HighPoolPriority;
PVOID Allocation = ExAllocatePool3(POOL_FLAG_PAGED, 100, 'abcd', &params, 1);

Mises à jour des pilotes pour les versions de Windows antérieures à Windows 10, version 2004

Si vous créez un pilote qui cible les versions de Windows antérieures à Windows 10 version 2004, vous devez utiliser les fonctions de wrapper inline force suivantes.

Vous devez également #define POOL_ZERO_DOWN_LEVEL_SUPPORT et appeler ExInitializeDriverRuntime pendant l’initialisation du pilote avant d’appeler les fonctions d’allocation de pool.

Fonctions inline définies localement

PVOID
NTAPI
ExAllocatePoolZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag
    )

PVOID
NTAPI
ExAllocatePoolQuotaZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag
    )

PVOID
NTAPI
ExAllocatePoolPriorityZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag,
    _In_ EX_POOL_PRIORITY Priority
    )

Reportez-vous au dernier en-tête wdm.h pour connaître le code d’implémentation de ces wrappers de code. Par exemple, il s’agit de l’implémentation pour ExAllocatePoolPriorityZero, montrant l’utilisation de RtlZeroMemory.

{
    PVOID Allocation;

    Allocation = ExAllocatePoolWithTagPriority((POOL_TYPE) (PoolType | POOL_ZERO_ALLOCATION),
                                               NumberOfBytes,
                                               Tag,
                                               Priority);

#if defined(POOL_ZERO_DOWN_LEVEL_SUPPORT)

    if ((!ExPoolZeroingNativelySupported) && (Allocation != NULL)) {
        RtlZeroMemory(Allocation, NumberOfBytes);
    }

#endif

    return Allocation;
}

Mappage d’anciennes API à de nouvelles API

Ancienne API Nouvelle API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

Exemple

// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code

// Before headers are pulled in (or compiler defined)
#define POOL_ZERO_DOWN_LEVEL_SUPPORT

// Once during driver initialization
// Argument can be any value
ExInitializeDriverRuntime(0);

// Replacement for each pool allocation
PVOID Allocation = ExAllocatePoolZero(PagedPool, 100, 'abcd');

Modèle de pilote : WDM, Generic

Comment tester

Au moment de la compilation :

  1. Exécutez Static Driver Verifier et spécifiez la règle UnSafeAllocatePool .

  2. Utilisez les étapes suivantes (décrites dans Utilisation du vérificateur de pilote statique pour rechercher des défauts dans les pilotes Windows) pour exécuter une analyse de votre code :

Pour plus d’informations, consultez Utilisation du vérificateur de pilote statique pour rechercher des défauts dans les pilotes.