Share via


UnSafeAllocatePool 규칙(wdm)

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 이전 버전의 Windows용 드라이버 업데이트, 버전 2004

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

드라이버 모델: WDM, 제네릭

테스트 방법

컴파일 시:

  1. 정적 드라이버 검증 도구를 실행하고 UnSafeAllocatePool 규칙을 지정합니다.

  2. 다음 단계( 정적 드라이버 검증 도구를 사용하여 Windows 드라이버에서 결함 찾기)를 사용하여 코드 분석을 실행합니다.

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