IrqlExAllocatePool 规则 (wdm)

IrqlExAllocatePool 规则指定驱动程序仅在 IRQL<=DISPATCH_LEVEL执行时调用 ExAllocatePoolWithTagExAllocatePoolWithTagPriority

在 DISPATCH_LEVEL 处执行的调用方必须为 PoolType 指定 NonPagedXxx 值。 在 IRQL <= APC_LEVEL 执行的调用方可以指定任何 POOL_TYPE 值。

驱动程序模型:WDM

使用此规则找到的 bug 检查 () Bug 检查0xC4:DRIVER_VERIFIER_DETECTED_VIOLATION (0x00020004) 、Bug 检查0xA:IRQL_NOT_LESS_OR_EQUAL

示例

在以下示例中, ExAllocatePoolWithTag 例程在 KeAcquireSpinLock 例程之后调用,该例程将 IRQL 设置为 DISPATCH_LEVEL。 ExAllocatePoolWithTag 例程通过 PagedPool 调用,这违反了规则。

NTSTATUS
DispatchRequest (
    __in PDEVICE_REQUEST DeviceRequest
    )
{  
    KIRQL OldIrql;
    KSPIN_LOCK SpinLock;
    NTSTATUS Status;
    ...

    KeInitializeSpinLock(&SpinLock);

    //
    // KeAcquireSpinLock sets IRQL to DISPATCH_LEVEL and the previous IRQL is 
    // written to OldIrql after the lock is acquired.
    //

    KeAcquireSpinLock(&SpinLock, &OldIrql);
    ...

    Status = ProcessRequest(DeviceRequest);

    //
    // KeReleaseSpinLock sets IRQL to the OldIrql returned by KeAcquireSpinLock.
    //

    KeReleaseSpinLock(&SpinLock, &OldIrql);
    ...
}

NTSTATUS
ProcessRequest (
    __in PDEVICE_REQUEST DeviceRequest
    )
{
    NTSTATUS Status;
    ...

    //
    // RULE VIOLATION! - IrqlExAllocatePool executing at DISPATCH_LEVEL must specify 
    //                   a NonPagedXxx value for PoolType. 
    //

    DeviceRequest->Context = ExAllocatePool(PagedPool, sizeof(REQUEST_CONTEXT));
    if (DeviceRequest->Context == NULL) {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }
    ...

    return Status;
}

如何测试

编译时

运行 静态驱动程序验证程序 并指定 IrqlExAllocatePool 规则。

使用以下步骤运行代码分析:
  1. 准备代码 (使用角色类型声明) 。
  2. 运行静态驱动程序验证程序。
  3. 查看和分析结果。

有关详细信息,请参阅 使用静态驱动程序验证程序查找驱动程序中的缺陷

运行时

运行 驱动程序验证程序 并选择 “DDI 符合性检查 ”选项。

适用于

ExAllocatePoolWithTagExAllocatePoolWithTagPriority

另请参阅

管理硬件优先级,防止使用旋转锁时出现错误和死锁