Règle UnSafeAllocatePool (kmdf)
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 :
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', ¶ms, 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 : WDF
Comment tester
Au moment de la compilation :
Exécutez Static Driver Verifier et spécifiez la règle UnSafeAllocatePool .
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.