Partilhar via


UseAfterFree (Consulta CodeQL de driver do Windows)

Visão geral

A consulta de CodeQL tem alta precisão, o que ajuda na automação de bugs, mas tem algumas limitações e, portanto, não será capaz de detectar todos os casos de defeitos UseAfterFree.

Um defeito UseAfterFree ocorre quando um bloco de memória alocado é usado depois de ter sido liberado (também conhecido como "ponteiro final").

O comportamento nesses casos é indefinido e, na prática, pode ter consequências não intencionais, incluindo corrupção de memória, uso de valores incorretos ou execução arbitrária de código.

Recomendação

Defina os ponteiros como NULL imediatamente após serem liberados.

Exemplo

No exemplo a seguir, pSomePointer será liberado somente se o valor Status não for zero, e antes de desreferenciar pSomePointer para chamar Method, Status será verificado novamente. Infelizmente, Status foi alterado entre as duas referências para pSomePointer, o que permite a possibilidade de que a chamada para pSomePointer->Method() seja realizada por um ponteiro liberado anteriormente.

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();
}

No exemplo corrigido, pSomePointer é definido para NULL imediatamente depois de ser liberado, e a condição para verificar se ele é seguro é chamar as verificações de pSomePointer->Method() para a condição adicional de modo a evitar o possível bug.

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();
}

Detalhes Adicionais

Essa consulta pode ser encontrada no repositório do Microsoft GitHub CodeQL. Consulte a página CodeQL e o teste de logotipo de ferramentas estáticas para obter mais informações sobre como os desenvolvedores de drivers do Windows podem baixar e executar o CodeQL.