UnSafeAllocatePool ルール (kmdf)

UnSafeAllocatePool 規則は、ドライバーがメモリの割り当てに非推奨の DDI を使用しないことをチェック重要なセキュリティ規則です。

UnsafeAllocatePool 規則は、ドライバーが次を呼び出さないことを指定します。

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

この規則は、プレビュー WDK ビルド 20236 以降で使用できます。

Windows 10 バージョン 2004 以降のバージョンのドライバー更新プログラム

Windows 10 バージョン 2004 以降を対象とするドライバーをビルドする場合は、代わりに代替 API ExAllocatePool2ExAllocatePool3 を使用します。

古い API 新しい API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

新しい API では、メモリ漏えいのバグの可能性を回避するために、プールの割り当てが既定でゼロになります。

ExAllocatePool/ExAllocatePoolWithTag

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

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

古いプール割り当て API は POOL_TYPE 引数を受け入れますが、新しい割り当て API は POOL_FLAGS 引数を受け入れます。 新しい POOL_FLAGS 引数を使用するように、関連付けられているコードを更新します。

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

新しい関数は、割り当て失敗時に既定で NULL を返すようになりました。 代わりに、アロケーターでエラー時に例外を発生させるには、 ExAllocatePool2 で説明されているように、POOL_FLAG_RAI Standard Edition_ON_FAILURE フラグを渡す必要があります。

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

Windows 10 バージョン 2004 より前のバージョンの Windows のドライバー更新プログラム

Windows 10 バージョン 2004 より前のバージョンの Windows を対象とするドライバーをビルドする場合は、次の強制インライン ラッパー関数を使用する必要があります。

また、プール割り当て関数を呼び出す 前に、ドライバーの初期化中に ExInitializeDriverRuntime を #define POOL_ZERO_DOWN_LEVEL_SUPPORT して呼び出す必要があります。

ローカルで定義されたインライン関数

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
    )

これらのコード ラッパーの実装コードについては、最新の wdm.h ヘッダーを参照してください。 たとえば、これは ExAllocatePoolPriorityZero の実装であり、 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;
}

古い API から新しい API へのマッピング

古い API 新しい API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

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

ドライバーモデル: WDF

テスト方法

コンパイル時:

  1. 静的ドライバー検証ツール を実行し、 UnSafeAllocatePool 規則を指定します。

  2. コードの分析を実行するには、次の手順 (Windows ドライバーで静的ドライバー検証ツールを使用して欠陥を見つける) を使用します。

詳細については、 「静的ドライバー検証ツールを使用してドライバー の欠陥を見つける」を参照してください。