Поделиться через


UseAfterFree (запрос Windows Driver CodeQL)

Обзор

Этот запрос CodeQL имеет высокую точность, которая помогает в автоматизации ошибок, но имеет некоторые ограничения, поэтому не сможет обнаружить все случаи дефектов UseAfterFree.

Дефект UseAfterFree возникает, когда выделенный блок памяти используется после того, как он был освобожден (также известен как "дальщий указатель").

Поведение в таких случаях не определено, и на практике может иметь непредвиденные последствия, включая повреждение памяти, использование неправильных значений или произвольное выполнение кода.

Рекомендация

Установите указатели на ЗНАЧЕНИЕ NULL сразу после освобождения.

Пример

В следующем примере освобождается только в том случае, pSomePointer если Status значение не равно нулю, а перед отменой pSomePointer ссылки на вызов MethodStatus снова проверка. К сожалению, 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, см. на странице "КодQL" и "Статические средства"