Compartir a través de


UseAfterFree (consulta de codeQL del controlador de Windows)

Información general

Esta consulta CodeQL tiene una alta precisión, que ayuda en la automatización de errores, pero tiene algunas limitaciones y, por tanto, no podrá detectar todos los casos de defectos de UseAfterFree.

Un defecto UseAfterFree se produce cuando se usa un bloque de memoria asignado después de liberarlo (también conocido como "puntero pendiente").

El comportamiento en estos casos no está definido y, en la práctica, puede tener consecuencias imprevistas, como daños en la memoria, el uso de valores incorrectos o la ejecución arbitraria de código.

Recomendación

Establezca punteros en NULL inmediatamente después de liberarse.

Ejemplo

En el ejemplo siguiente, pSomePointer solo se libera si el valor de Status no era cero y antes de desreferenciar pSomePointer para llamar a Method, Status se vuelve a comprobar. Desafortunadamente, Status se cambió entre las dos referencias a pSomePointer, lo que permite la posibilidad de que la llamada a pSomePointer->Method() se realice en un puntero liberado previamente.

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

En el ejemplo corregido, pSomePointer se establece en NULL inmediatamente después de liberarse y la condición para comprobar si es seguro llamar a pSomePointer->Method() comprueba esta condición adicional para evitar el posible error.

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

Detalles adicionales

Esta consulta se puede encontrar en el repositorio de Microsoft GitHub CodeQL. Consulte la página CodeQL y la prueba de logotipos de herramientas estáticas para obtener más información sobre cómo los desarrolladores de controladores de Windows pueden descargar y ejecutar CodeQL.