다음을 통해 공유


UseAfterFree(Windows 드라이버 CodeQL 쿼리)

개요

CodeQL 쿼리 는 정밀도가 높기 때문에 버그 자동화에 도움이 되지만 몇 가지 제한 사항이 있으므로 UseAfterFree 결함의 모든 사례를 검색할 수 없습니다.

UseAfterFree 결함은 할당된 메모리 블록이 해제된 후 사용될 때 발생합니다("현수 포인터"라고도 함).

이러한 경우 동작은 정의되지 않으며 실제로 메모리 손상, 잘못된 값 사용 또는 임의 코드 실행을 포함하여 의도하지 않은 결과가 발생할 수 있습니다.

추천

해제된 직후 NULL에 대한 포인터를 설정합니다.

예시

다음 예제 pSomePointer 에서는 값이 0이 아닌 경우에만 Status 해제되고 호출 MethodStatus 을 역참조 pSomePointer 하기 전에 다시 확인됩니다. 아쉽게도 Status 두 참조 pSomePointer간에 변경되어 이전에 해제된 포인터를 pSomePointer->Method() 통해 호출이 수행될 가능성이 있습니다.

NTSTATUS Status = x();

if (Status != 0)
{
    // Release pSomePointer if the call to x() failed

    ExFreePool(pSomePointer);
}

Status = y();

if (Status == 0)
{
    // Because Status may no longer be the same value than it was before the pointer was released,
    // this code may be using pSomePointer after it was freed, potentially executing arbitrary code.

    Status = pSomePointer->Method();
}

수정된 예제 pSomePointer 에서는 해제된 직후로 NULL 설정되며, 가능한 버그를 방지하기 위해 이 추가 조건을 호출 pSomePointer->Method() 하는 것이 안전한지 확인하는 조건입니다.

NTSTATUS Status = x();

if (Status != 0)
{
    // Release pSomePointer if the call to x() failed

    ExFreePool(pSomePointer);

    // Setting pSomePointer to NULL after being freed
    pSomePointer = NULL;
}

Status = y();

// If pSomePointer was freed above, its value must have been set to NULL
if (Status == 0 && pSomePointer != NULL)
{
    Status = pSomePointer->Method();
}

추가 정보

이 쿼리는 Microsoft GitHub CodeQL 리포지토리에서 찾을 수 있습니다. Windows 드라이버 개발자가 CodeQL을 다운로드하고 실행하는 방법에 대한 자세한 내용은 CodeQL 및 정적 도구 로고 테스트 페이지를 참조하세요.