Condividi tramite


Regola UnSafeAllocatePool (kmdf)

La regola UnSafeAllocatePool è una regola di sicurezza importante che verifica che un driver non usi DDI deprecati per allocare memoria.

La regola UnsafeAllocatePool specifica che il driver non deve chiamare:

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

Questa regola è disponibile in anteprima delle build WDK 20236 e successive.

Aggiornamenti dei driver per le versioni di Windows 10, versione 2004 e versioni successive

Se si sta creando un driver destinato Windows 10, versione 2004 e successiva, usare invece le API sostitutive ExAllocatePool2 e ExAllocatePool3.

API precedente Nuova API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

Per impostazione predefinita, le nuove API non avranno allocazioni di pool, per evitare possibili bug di divulgazione della memoria.

ExAllocatePool/ExAllocatePoolWithTag

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

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

Le API di allocazione del pool precedenti accettano un argomento POOL_TYPE , ma le nuove API di allocazione accettano un argomento POOL_FLAGS . Aggiornare qualsiasi codice associato per usare il nuovo argomento POOL_FLAGS .

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

La nuova funzione restituirà ora NULL in caso di errore di allocazione per impostazione predefinita. Per avere l'allocatore generare invece un'eccezione in caso di errore, il flag di POOL_FLAG_RAISE_ON_FAILURE deve essere passato come illustrato in 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);

Aggiornamenti del driver per le versioni di Windows precedenti a Windows 10 versione 2004

Se si sta creando un driver destinato alle versioni di Windows prima di Windows 10, versione 2004, è necessario usare le funzioni di wrapper inline seguenti.

È anche necessario #define POOL_ZERO_DOWN_LEVEL_SUPPORT e chiamare ExInitializeDriverRuntime durante l'inizializzazione del driver prima di chiamare le funzioni di allocazione del pool.

Funzioni inline definite in locale

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
    )

Fare riferimento all'intestazione wdm.h più recente per il codice di implementazione per questi wrapper di codice. Ad esempio, questa è l'implementazione di ExAllocatePoolPriorityZero, che mostra l'uso di 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;
}

Mapping delle API precedenti alle nuove API

API precedente Nuova API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

Esempio

// 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');

Modello di driver: WDF

Come eseguire il test

In fase di compilazione:

  1. Eseguire il verifica driver statico e specificare la regola UnSafeAllocatePool .

  2. Seguire questa procedura (disponibile in Using Static Driver Verifier to Find Defects in Windows Drivers) per eseguire un'analisi del codice:

Per altre informazioni, vedere Uso del verificatore driver statico per trovare i difetti nei driver.