UnSafeAllocatePool-Regel (kmdf)

Die UnSafeAllocatePool-Regel ist eine wichtige Sicherheitsregel, die überprüft, ob ein Treiber keine veralteten DDIs verwendet, um Arbeitsspeicher zuzuweisen.

Die UnsafeAllocatePool-Regel gibt an, dass der Treiber folgendes nicht aufrufen soll:

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

Diese Regel ist in der Vorschauversion von WDK-Builds 20236 und höher verfügbar.

Treiberupdates für Versionen von Windows 10, Version 2004 und höher

Wenn Sie einen Treiber für Windows 10, Version 2004 und höher, erstellen, verwenden Sie stattdessen die Ersatz-APIs ExAllocatePool2 und ExAllocatePool3.

Alte API Neue API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

Die neuen APIs weisen standardmäßig keine Poolzuordnungen auf, um mögliche Fehler bei der Speicheroffenlegung zu vermeiden.

ExAllocatePool/ExAllocatePoolWithTag

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

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

Die alten Poolzuordnungs-APIs akzeptieren ein POOL_TYPE-Argument , aber die neuen Zuordnungs-APIs akzeptieren ein POOL_FLAGS-Argument . Aktualisieren Sie den zugeordneten Code, um das neue argument POOL_FLAGS zu verwenden.

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

Die neue Funktion gibt jetzt standardmäßig NULL bei Zuordnungsfehler zurück. Damit der Zuweisungsgeber stattdessen eine Ausnahme bei Einem Fehler auslöst, muss das POOL_FLAG_RAISE_ON_FAILURE-Flag übergeben werden, wie in ExAllocatePool2 beschrieben.

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

Treiberupdates für Versionen von Windows vor Windows 10, Version 2004

Wenn Sie einen Treiber für Windows-Versionen vor Windows 10 Version 2004 erstellen, müssen Sie die folgenden Force-Inline-Wrapperfunktionen verwenden.

Außerdem müssen Sie ExInitializeDriverRuntime während der Treiberinitialisierung #define POOL_ZERO_DOWN_LEVEL_SUPPORT und aufrufen, bevor Sie die Poolzuordnungsfunktionen aufrufen.

Lokal definierte Inlinefunktionen

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
    )

Den Implementierungscode für diese Code wrapper finden Sie im neuesten wdm.h-Header. Dies ist beispielsweise die Implementierung für ExAllocatePoolPriorityZero, die die Verwendung von RtlZeroMemory zeigt.

{
    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;
}

Zuordnung alter APIs zu neuen APIs

Alte API Neue API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

Beispiel

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

Treibermodell: WDF

So führen Sie einen Test durch

Zur Kompilierzeit:

  1. Führen Sie Static Driver Verifier aus, und geben Sie die UnSafeAllocatePool-Regel an.

  2. Führen Sie die folgenden Schritte ( unter Verwenden der statischen Treiberüberprüfung zum Suchen von Fehlern in Windows-Treibern) aus, um eine Analyse Ihres Codes auszuführen:

Weitere Informationen finden Sie unter Verwenden der statischen Treiberüberprüfung, um Fehler in Treibern zu finden.