Regla UnSafeAllocatePool (kmdf)

La regla UnSafeAllocatePool es una regla de seguridad importante que comprueba que un controlador no usa DDIs en desuso para asignar memoria.

La regla UnsafeAllocatePool especifica que el controlador no debe llamar a:

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

Esta regla está disponible en versiones preliminares de WDK 20236 y versiones posteriores.

Actualizaciones de controladores para versiones de Windows 10, versión 2004 y posteriores

Si va a compilar un controlador destinado a Windows 10, versión 2004 y posteriores, use las API de reemplazo ExAllocatePool2 y ExAllocatePool3 en su lugar.

API antigua Nueva API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

Las nuevas API no tendrán asignaciones de grupo de forma predeterminada para ayudar a evitar posibles errores de divulgación de memoria.

ExAllocatePool/ExAllocatePoolWithTag

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

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

Las API de asignación de grupos antiguas aceptan un argumento POOL_TYPE , pero las nuevas API de asignación aceptan un argumento POOL_FLAGS . Actualice cualquier código asociado para usar el nuevo argumento POOL_FLAGS .

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

La nueva función ahora devolverá NULL al error de asignación de forma predeterminada. Para que el asignador genere una excepción en caso de error, la marca POOL_FLAG_RAISE_ON_FAILURE debe pasarse como se describe en 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);

Actualizaciones de controladores para versiones de Windows anteriores a Windows 10, versión 2004

Si va a compilar un controlador destinado a versiones de Windows anteriores a Windows 10, versión 2004, debe usar las siguientes funciones contenedoras insertadas.

También debe #define POOL_ZERO_DOWN_LEVEL_SUPPORT y llamar a ExInitializeDriverRuntime durante la inicialización del controlador antes de llamar a las funciones de asignación del grupo.

Funciones insertadas 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 el encabezado wdm.h más reciente para el código de implementación de estos contenedores de código. Por ejemplo, esta es la implementación de ExAllocatePoolPriorityZero, que muestra el 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;
}

Asignación de API antiguas a nuevas API

API antigua Nueva API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

Ejemplo

// 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 controlador: WDF

Cómo probar

En tiempo de compilación:

  1. Ejecute el Comprobador de controladores estáticos y especifique la regla UnSafeAllocatePool .

  2. Use los pasos siguientes (que se encuentran en Uso del comprobador de controladores estáticos para buscar defectos en controladores de Windows) para ejecutar un análisis del código:

Para obtener más información, consulte Uso del comprobador de controladores estáticos para buscar defectos en controladores.