AddressSanitizer asistido por hardware (HWASan) es una herramienta de detección de errores de memoria similar a AddressSanitizer . HWASan usa mucha menos RAM en comparación con ASan, lo que lo hace adecuado para la desinfección de todo el sistema. HWASan solo está disponible en Android 10 y superior, y solo en hardware AArch64.
Aunque es principalmente útil para el código C/C++, HWASan también puede ayudar a depurar el código Java que causa bloqueos en C/C++ que se usa para implementar interfaces Java. Es útil porque detecta los errores de memoria cuando ocurren y lo señala directamente al código responsable.
Puede flashear imágenes HWASan preconstruidas a dispositivos Pixel compatibles desde ci.android.com ( instrucciones de configuración detalladas ).
Comparado con el ASan clásico, HWASan tiene:
- Sobrecarga de CPU similar (~2x)
- Sobrecarga de tamaño de código similar (40 - 50%)
- Sobrecarga de RAM mucho menor (10% - 35%)
HWASan detecta el mismo conjunto de errores que ASan:
- Desbordamiento/subdesbordamiento del búfer de pila y montón
- Uso del montón después de gratis
- Uso de pila fuera del alcance
- Doble gratis/wild gratis
Además, HWASan detecta el uso de la pila después de la devolución.
Detalles y limitaciones de la implementación
HWASan se basa en el enfoque de etiquetado de memoria , donde un pequeño valor de etiqueta aleatorio se asocia tanto con punteros como con rangos de direcciones de memoria. Para que un acceso a la memoria sea válido, el puntero y las etiquetas de memoria deben coincidir. HWASan se basa en la función ARMv8 para ignorar el byte superior (TBI), también llamada etiquetado de dirección virtual , para almacenar la etiqueta del puntero en los bits más altos de la dirección.
Puede leer más sobre el diseño de HWASan en el sitio de documentación de Clang.
Por diseño, HWASan no tiene las zonas rojas de tamaño limitado de ASan para detectar desbordamientos ni la cuarentena de capacidad limitada de ASan para detectar el uso después de la liberación. Por esta razón, HWASan puede detectar un error sin importar cuán grande sea el desbordamiento o cuánto tiempo hace que se desasignó la memoria. Esto le da a HWASan una gran ventaja sobre ASan.
Sin embargo, HWASan tiene un número limitado de posibles valores de etiqueta (256), lo que significa que hay un 0,4 % de probabilidad de perder algún error durante una ejecución del programa.
Requisitos
HWASan requiere que el kernel de Linux acepte punteros etiquetados en argumentos de llamadas al sistema. El soporte para esto se implementó en los siguientes conjuntos de parches ascendentes:
- arm64 dirección etiquetada ABI
- arm64: quitar la etiqueta de los punteros de usuario pasados al kernel
- mm: Evite crear alias de direcciones virtuales en brk()/mmap()/mremap()
- arm64: validar direcciones etiquetadas en access_ok() llamadas desde hilos del kernel
Estos parches están disponibles como backports en el kernel común de Android en las ramas android-4.14 y superiores, pero no en las ramas específicas de Android 10, como android-4.14-q .
El soporte de espacio de usuario para HWASan está disponible a partir de Android 11 .
Si está compilando con una cadena de herramientas personalizada, asegúrese de que incluya todo hasta LLVM commit c336557f .
Usando HWASan
Use los siguientes comandos para construir toda la plataforma usando HWASan:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Para mayor comodidad, puede agregar la configuración SANITIZE_TARGET a una definición de producto, similar a aosp_coral_hwasan .
A diferencia de ASan, con HWASan no hay necesidad de construir dos veces. Las compilaciones incrementales simplemente funcionan, no hay instrucciones especiales de flasheo ni requisitos de borrado, se admiten ejecutables estáticos y está bien omitir la desinfección de cualquier biblioteca que no sea libc
. Tampoco existe el requisito de que si se desinfecta una biblioteca, cualquier ejecutable que se vincule a ella también deba ser desinfectado.
Para omitir la sanitización de un módulo, use LOCAL_NOSANITIZE := hwaddress
o sanitize: { hwaddress: false }
.
Los módulos individuales se pueden desinfectar con HWASan, con la advertencia de que libc
también está HWASan-ificado. Esto se puede hacer agregando sanitize: { hwaddress: true }
a la respectiva definición del módulo Android.bp
. Toda la plataforma Android está construida con HWASan cuando se usa una compilación con el _hwasan
(incluida libc
) y, como tal, no es necesario desinfectar manualmente libc
para las compilaciones HWASan.
Mejores rastros de pila
HWASan utiliza un desbobinador rápido basado en un puntero de cuadro para registrar un seguimiento de la pila para cada evento de asignación y desasignación de memoria en el programa. Android habilita los punteros de marco en el código AArch64 de forma predeterminada, por lo que funciona muy bien en la práctica. Si necesita relajarse a través del código administrado, establezca HWASAN_OPTIONS=fast_unwind_on_malloc=0
en el entorno de proceso. Tenga en cuenta que los seguimientos de pila de acceso a memoria incorrectos utilizan el desenrollador "lento" de forma predeterminada; esta configuración solo afecta a los seguimientos de asignación y desasignación. Esta opción puede hacer un uso intensivo de la CPU, dependiendo de la carga.
Simbolización
Consulte Simbolización en la documentación de ASan.
HWASan en aplicaciones
Similar a AddressSanitizer, HWASan no puede ver el código Java, pero puede detectar errores en las bibliotecas JNI. A diferencia de ASan, no se admite la ejecución de aplicaciones HWASan en un dispositivo que no sea HWASan.
En un dispositivo HWASan, las aplicaciones se pueden comprobar con HWASan creando su código con SANITIZE_TARGET:=hwaddress
en Make o -fsanitize=hwaddress
en las marcas del compilador. Consulte la documentación del desarrollador de la aplicación para obtener más detalles.