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.