Consulta Cómo interpretar los informes de HWASan para obtener información sobre cómo leer las fallas de HWASan.
Hardware-assisted AddressSanitizer (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 sanitización de todo el sistema. HWASan solo está disponible en Android 10 y versiones posteriores, y solo en hardware AArch64.
Si bien es principalmente útil para el código C/C++, HWASan también puede ayudar a depurar el código Java que provoca fallas en C/C++ que se usan para implementar interfaces de Java. Es útil porque detecta errores de memoria cuando ocurren y te indica directamente el código responsable.
En comparación con la versión clásica de ASan, HWASan tiene las siguientes características:
- Sobrecarga de la CPU similar (alrededor de 2 veces más)
- Sobrecarga del tamaño de código similar (del 40 al 50%)
- Sobrecarga de la RAM mucho menor (del 10 al 35%)
HWASan detecta el mismo conjunto de errores que ASan:
- Desabastecimiento de búfer de pila
- Uso de pila después de liberación
- Uso de pila fuera del alcance
- Cierre doble o cierre wild
Además, HWASan detecta el uso de pila después de la devolución.
HWASan (igual que ASan) es compatible con UBSan, y ambos se pueden habilitar en un destino al mismo tiempo.
Detalles y limitaciones de la implementación
HWASan se basa en el enfoque de etiquetado de memoria, en el que se asocia un pequeño valor de etiqueta aleatorio tanto con los punteros como con los rangos de direcciones de memoria. Para que un acceso a la memoria sea válido, las etiquetas de puntero y de memoria deben coincidir. HWASan se basa en la función de ARMv8 Top Byte Ignore (TBI), también llamada etiquetado de direcciones virtuales, para almacenar la etiqueta del puntero en los bits más significativos de la dirección.
Puedes obtener más información 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 este motivo, HWASan puede detectar un error sin importar qué tan grande sea el desbordamiento o hace cuánto tiempo se liberó la memoria. Esto le da a HWASan una gran ventaja sobre ASan.
Sin embargo, HWASan tiene una cantidad limitada de valores de etiquetas posibles (256), lo que significa que hay un 0.4% de probabilidad de no detectar ningún error durante una ejecución del programa.
Requisitos
Las versiones recientes (4.14 y posteriores) del kernel común de Android admiten HWASan de forma predeterminada. Las ramas específicas de Android 10 no admiten HWASan.
La compatibilidad con el espacio del usuario para HWASan está disponible a partir de Android 11.
Si trabajas con un kernel diferente, HWASan requiere que el kernel de Linux acepte punteros etiquetados en los argumentos de llamadas al sistema. La compatibilidad con esta función se implementó en los siguientes conjuntos de parches upstream:
- ABI de direcciones etiquetadas de arm64
- arm64: Quita las etiquetas de los punteros de usuario que se pasan al kernel
- mm: Avoid creating virtual address aliases in brk()/mmap()/mremap()
- arm64: Valida las direcciones etiquetadas en access_ok() llamadas desde subprocesos del kernel
Si compilas con una cadena de herramientas personalizada, asegúrate de que incluya todo hasta la confirmación de LLVM c336557f.
Cómo usar HWASan
Usa los siguientes comandos para compilar toda la plataforma con HWASan:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Para mayor comodidad, puedes agregar el parámetro de configuración SANITIZE_TARGET a una definición de producto, de forma similar a aosp_coral_hwasan.
Para los usuarios que conocen AddressSanitizer, se elimina gran parte de la complejidad de la compilación:
- No es necesario ejecutar make dos veces.
- Las compilaciones incrementales funcionan de inmediato.
- No es necesario escribir la partición userdata en la memoria flash.
También se quitaron algunas restricciones de AddressSanitizer:
- Se admiten los ejecutables estáticos.
- Se puede omitir la limpieza de cualquier destino que no sea libc. A diferencia de ASan, no se requiere que, si se sanitiza una biblioteca, también se debe sanitizar cualquier ejecutable que la vincule.
Puedes cambiar entre imágenes HWASan y normales con el mismo número de compilación (o uno superior) sin problemas. No es necesario borrar el dispositivo.
Para omitir la limpieza de un módulo, usa LOCAL_NOSANITIZE := hwaddress
(Android.mk) o sanitize: { hwaddress: false }
(Android.bp).
Cómo limpiar destinos individuales
HWASan se puede habilitar por destino en una compilación normal (sin sanitizar), siempre y cuando libc.so
también esté sanitizado. Agrega hwaddress: true
al bloque de limpieza en "libc_defaults"
en bionic/libc/Android.bp. Luego, haz lo mismo en el destino en el que estás trabajando.
Ten en cuenta que la sanitización de libc permite etiquetar las asignaciones de memoria del montón en todo el sistema, así como verificar las etiquetas para las operaciones de memoria dentro de libc.so
. Esto puede detectar errores incluso en los archivos binarios en los que no se habilitó HWASan si el acceso a la memoria incorrecto se encuentra en libc.so
(p. ej., pthread_mutex_unlock()
en un mutex delete()
.
No es necesario cambiar ningún archivo de compilación si toda la plataforma se compila con HWASan.
Mejores seguimientos de pila
HWASan usa un desenredador rápido basado en punteros de marco para registrar un seguimiento de 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 esto funciona muy bien en la práctica. Si necesitas deshacer la pila de llamadas a través del código administrado, establece HWASAN_OPTIONS=fast_unwind_on_malloc=0
en el entorno del proceso. Ten en cuenta que los seguimientos de pila de acceso a memoria incorrecto usan el desenredador "lento" de forma predeterminada. Este parámetro de configuración solo afecta los seguimientos de asignación y desasignación. Esta opción puede consumir muchos recursos de CPU, según la carga.
Simbología
Consulta Símbolos en "Cómo interpretar los informes de HWASan".
HWASan en apps
Al igual que AddressSanitizer, HWASan no puede ver el código Java, pero sí puede detectar errores en las bibliotecas de JNI. Hasta Android 14, no se admitía la ejecución de apps de HWASan en dispositivos que no fueran de HWASan.
En un dispositivo HWASan, las apps se pueden verificar con HWASan compilando su código con SANITIZE_TARGET:=hwaddress
en Make o -fsanitize=hwaddress
en las marcas del compilador.
En un dispositivo que no sea HWASan (que ejecute Android 14 o versiones posteriores), se debe agregar un parámetro de configuración del archivo wrap.sh LD_HWASAN=1
.
Consulta la documentación para desarrolladores de apps para obtener más detalles.