Analizabilidad
Esta extensión opcional al lenguaje C limita los resultados potenciales de la ejecución de algunas formas de comportamiento indefinido, lo que mejora la eficacia del análisis estático de dichos programas. La analizabilidad sólo está garantizada si se activa la constante de macro predefinida __STDC_ANALYZABLE__(C11) está definido por el compilador.
Si el compilador soporta la analizabilidad, cualquier lenguaje o construcción de biblioteca cuyo comportamiento es indefinido se clasificará más adelante como comportamiento indefinido crítico y limitado, y el comportamiento de todos los casos de comportamiento indefinido "limitado" se limitan como se indica a continuación.
Contenido |
[editar] Comportamiento indefinido crítico
El comportamiento indefinido crítico es el comportamiento indefinido que puede realizar una escritura de memoria o una lectura de memoria volátil fuera de los límites de cualquier objeto. Un programa que tiene un comportamiento indefinido crítico puede ser susceptible a ataques de seguridad.
Sólo los siguientes comportamientos indefinidos son críticos:
- acceder a un objeto fuera de su vida útil. (por ejemplo, a través de un puntero colgante)
- escribir a un objeto cuyas declaraciones no son compatibles
- llamar a una función a través de un puntero de función cuyo tipo no es compatible con el tipo de función a la que apunta
- la expresión lvalue se evalúa, pero no designa un objeto
- intento de modificación de una cadena literal
- dereferenciar un puntero inválido (nulo, indeterminado, etc.) o inactivo.
- modificación de un objeto const a través de un puntero no const
- llamada a una función o macro de la biblioteca estándar con un argumento no válido
- llamada a una función variádica de la librería estándar con un tipo de argumento inesperado (por ejemplo, llamar a printf con un argumento del tipo que no coincide con su especificador de conversión)
- longjmp donde no hay setjmp hasta el ámbito de llamada, a través de hilos, o desde el ámbito de un tipo de VM
- cualquier uso de un puntero que haya sido deslocalizado por free o realloc.
- cualquier función de cadenas o cadenas ancha que acceda a una matriz fuera de los límites.
[editar] Comportamiento indefinido limitado
El comportamiento indefinido limitado es un comportamiento indefinido que no puede realizar una escritura de memoria ilegal, aunque puede atrapar y puede producir o almacenar valores indeterminados.
- Todo comportamiento indefinido que no esté listado como crítico está limitado, incluyendo
- carreras de datos multihilo
- utilización de valores indeterminados con una duración de almacenamiento automática
- violaciones de alineación estrictas
- acceso a objetos desalineados
- desbordamiento de un entero con signo
- efectos secundarios no secuenciados que modifican el mismo escalar o modifican y leen el mismo escalar
- desbordamiento de la conversión de flotante a entero o de puntero a entero
- desplazamiento en el sentido de los bits por un número de bits negativo o demasiado grande
- división entera por cero
- uso de una expresión void
- asignación directa o memcpy de objetos superpuestos inexactamente
- violaciones de restricciones
- etc. Todo comportamiento indefinido que no esté en la lista crítica.
[editar] Observaciones
El comportamiento indefinido limitado desactiva ciertas optimizaciones: la compilación con analizabilidad habilitada preserva la causalidad del código fuente, que de otro modo podría ser violada por un comportamiento indefinido.
La extensión de la analizabilidad permite, como una forma de comportamiento definido por la implementación, que el manejador de restricciones de tiempo de ejecución sea invocado cuando ocurre una vulnerabilidad.
[editar] Referencias
- Standard C11 (ISO/IEC 9899:2011):
- 6.10.8.3/1 Conditional feature macros (p: 177)
- Annex L Analyzability (p: 652-653)