UseAfterFree(Windows 드라이버 CodeQL 쿼리)

개요

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

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

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

권장 사항

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

예제

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

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 및 정적 도구 로고 테스트 페이지를 참조하세요.