Bytes paralelos de AddressSanitizer
Resumimos brevemente el concepto de bytes de sombra y cómo los puede usar la implementación en tiempo de ejecución de /fsanitize=address . Para obtener más información, nos referimos al documento sédico y al algoritmo AddressSanitizer.
Concepto básico
Cada 8 bytes del espacio de direcciones virtuales de la aplicación se puede describir con un byte de sombra.
Un byte de sombra describe cuántos bytes son accesibles actualmente de la siguiente manera:
- 0 significa los 8 bytes
- 1-7 significa de uno a siete bytes
- Los números negativos codifican el contexto del tiempo de ejecución que se usará para los diagnósticos de informes.
Leyenda de bytes de sombra
Considere esta leyenda de bytes de sombra donde se definen todos los números negativos:
Asignación: descripción del espacio de direcciones
Cada 8 bytes del espacio de direcciones virtuales de la aplicación alineado con "0-mod-8" se puede asignar al byte de sombra que describe esa ranura en el espacio de direcciones virtuales. Esta asignación se puede realizar con un desplazamiento simple y agregar.
En x86:
char shadow_byte_value = *((Your_Address >> 3) + 0x30000000)
En x64:
char shadow_byte_value = *((Your_Address >> 3) + _asan_runtime_assigned_offset)
Generación de código: pruebas
Tenga en cuenta cómo se pueden escribir bytes de sombra específicos, ya sea por el código generado por el compilador, los datos estáticos o el tiempo de ejecución. Este pseudocódigo muestra cómo es posible generar una comprobación que precede a cualquier carga o almacén:
ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
ReportAndCrash(Addr);
}
Al instrumentar una referencia de memoria de menos de 8 bytes de ancho, la instrumentación es ligeramente más compleja. Si el valor de la sombra es positivo (lo que significa que solo se puede acceder a los primeros k bytes de la palabra de 8 bytes), es necesario comparar los últimos 3 bits de la dirección con k.
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
ReportAndCrash(Addr);
}
Tanto el tiempo de ejecución como el código generado por el compilador escriben bytes de sombra. Estos bytes de sombra permiten o revocan el acceso cuando los ámbitos finalizan o se libera el almacenamiento. Las comprobaciones anteriores leen bytes de sombra que describen "ranuras" de 8 bytes en el espacio de direcciones de la aplicación, en un momento determinado de la ejecución del programa. Además de estas comprobaciones generadas explícitamente, el tiempo de ejecución también comprueba los bytes de sombra después de interceptar (o "enlazar") muchas funciones de CRT.
Para obtener más información, vea la lista de funciones interceptadas.
Establecimiento de bytes de sombra
Tanto el código que genera el compilador como el tiempo de ejecución addressSanitizer pueden escribir bytes de sombra. Por ejemplo, el compilador puede establecer bytes de sombra para permitir el acceso de tamaño fijo a las locales de pila definidas en un ámbito interno. El tiempo de ejecución puede rodear variables globales en la sección de datos con bytes de sombra.
Vea también
Información general de AddressSanitizer
Problemas conocidos de AddressSanitizer
Referencia de lenguaje y compilación de AddressSanitizer
Referencia del entorno de ejecución de AddressSanitizer
Nube o pruebas distribuidas de AddressSanitizer
Integración del depurador de AddressSanitizer
Ejemplos de errores de AddressSanitizer