UnSafeAllocatePool-Regel (wdm)

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

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

Mit den neuen APIs werden standardmäßig keine Poolzuordnungen durchgeführt, 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 Zuordnungsfehlern zurück. Damit die Zuweisung stattdessen eine Ausnahme bei einem Fehler auslöst, muss das flag POOL_FLAG_RAISE_ON_FAILURE ü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 Frühere Versionen von Windows als Windows 10, Version 2004

Wenn Sie einen Treiber erstellen, der auf Versionen von Windows vor Windows 10 Version 2004 abzielt, müssen Sie die folgenden Force-Inlinewrapperfunktionen 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 Codewrapper 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: WDM, Generic

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 Auffinden 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.