Regra UnSafeAllocatePool (kmdf)

A regra UnSafeAllocatePool é uma regra de segurança importante que verifica se um driver não está usando DDIs preteridos para alocar memória.

A regra UnsafeAllocatePool especifica que o driver não deve chamar:

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

Essa regra está disponível nas versões prévias do WDK builds 20236 e superiores.

Atualizações de driver para versões do Windows 10, versão 2004 e posteriores

Se você estiver criando um driver direcionado Windows 10, versão 2004 e posterior, use as APIs de substituição ExAllocatePool2 e ExAllocatePool3.

API antiga Nova API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

As novas APIs não terão alocações de pool por padrão, para ajudar a evitar possíveis bugs de divulgação de memória.

ExAllocatePool/ExAllocatePoolWithTag

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

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

As APIs de alocação de pool antigas aceitam um argumento POOL_TYPE , mas as novas APIs de alocação aceitam um argumento POOL_FLAGS . Atualize qualquer código associado para usar o novo argumento POOL_FLAGS .

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

A nova função agora retornará NULL em caso de falha de alocação por padrão. Para que o alocador gere uma exceção na falha, o sinalizador POOL_FLAG_RAISE_ON_FAILURE deve ser passado conforme discutido em 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);

Atualizações de driver para versões do Windows anteriores a Windows 10, versão 2004

Se você estiver criando um driver que tenha como destino versões do Windows antes do Windows 10, versão 2004, deverá usar as seguintes funções de wrapper de força embutida.

Você também deve #define POOL_ZERO_DOWN_LEVEL_SUPPORT e chamar ExInitializeDriverRuntime durante a inicialização do driver antes de chamar as funções de alocação do pool.

Funções embutidas definidas localmente

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
    )

Consulte o cabeçalho wdm.h mais recente para o código de implementação desses wrappers de código. Por exemplo, essa é a implementação de ExAllocatePoolPriorityZero, mostrando o uso 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;
}

Mapeamento de APIs antigas para novas APIs

API antiga Nova API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

Exemplo

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

Modelo de driver: WDF

Como testar

Em tempo de compilação:

  1. Execute o Verificador de Driver Estático e especifique a regra UnSafeAllocatePool .

  2. Use as seguintes etapas (encontradas em Usando o Verificador de Driver Estático para Localizar Defeitos em Drivers do Windows) para executar uma análise do código:

Para obter mais informações, consulte Usando o Verificador de Driver Estático para localizar defeitos em drivers.