UnSafeAllocatePool 규칙(kmdf)

UnSafeAllocatePool 규칙은 드라이버가 사용되지 않는 DPI를 사용하여 메모리를 할당하지 않는지 확인하는 중요한 보안 규칙입니다.

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는 가능한 메모리 공개 버그를 방지하기 위해 기본적으로 풀 할당을 0으로 설정합니다.

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_RAISE_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 헤더를 참조하세요. 예를 들어 이는 RtlZeroMemory의 사용을 보여 주는 ExAllocatePoolPriorityZero에 대한 구현입니다.

{
    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 드라이버에서 결함 찾기)를 사용하여 코드 분석을 실행합니다.

자세한 내용은 정적 드라이버 검증 도구로 드라이버에서 결함 찾기를 참조하세요.