Partilhar via


UseAfterFree (Consulta do CodeQL do Driver do Windows)

Visão geral

Esta query 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 detetar todos os casos de falhas de UseAfterFree.

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

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 é liberado somente se Status o valor não for zero, e antes de desreferenciar pSomePointer para chamar Method, Status é 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() está a ser realizada sobre um ponteiro previamente libertado.

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 como NULL imediatamente após ser liberado, e a condição para verificar se é seguro chamar pSomePointer->Method() verifica essa condição adicional para 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

Esta consulta pode ser encontrada no repositório Microsoft GitHub CodeQL. Consulte a página CodeQL e Teste de logotipo de ferramentas estáticas para obter detalhes sobre como os desenvolvedores de drivers do Windows podem baixar e executar o CodeQL.