Consulta Cómo interpretar los informes de HWASan para obtener información sobre cómo leer las fallas de HWASan.
AddressSanitizer asistida 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 limpieza de todo el sistema. HWASan solo está disponible en Android 10 y versiones posteriores, y solo en hardware AArch64.
Aunque es útil principalmente para el código C/C++, HWASan también puede ayudar a depurar el código Java que causa fallas en C/C++ que se usa para implementar interfaces de Java. Es útil porque detecta errores de memoria cuando ocurren y te dirige directamente al código responsable.
Puedes escribir en la memoria flash imágenes de HWASan compiladas previamente en dispositivos Pixel compatibles desde ci.android.com (instrucciones de configuración detalladas).
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 la pila después de la devolución.
HWASan (al 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 con punteros y 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 de omisión de bytes superiores (TBI) de ARMv8, también llamada etiquetado de direcciones virtuales, para almacenar la etiqueta del puntero en los bits más altos de la dirección.
Puedes obtener más información sobre el diseño de HWASan en el sitio de documentación de Clang.
De forma predeterminada, 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 liberar. Por este motivo, HWASan puede detectar un error, sin importar el tamaño del desbordamiento ni cuánto tiempo hace que se desasignó la memoria. Esto le da a HWASan una gran ventaja sobre ASan.
Sin embargo, HWASan tiene una cantidad limitada de valores de etiqueta posibles (256), lo que significa que existe una probabilidad del 0.4% de que se pierda cualquier error durante una ejecución del programa.
Requisitos
Las versiones recientes (4.14 y versiones posteriores) del kernel común de Android admiten HWASan lista para usar. Las ramas específicas de Android 10 no son compatibles con HWASan.
La compatibilidad con el espacio de 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 llamada del sistema. La compatibilidad con esto se implementó en los siguientes conjuntos de parches upstream:
- ABI de dirección etiquetada arm64
- arm64: Se quitan las etiquetas de los punteros de usuario que se pasan al kernel.
- mm: Evita crear alias de direcciones virtuales en brk()/mmap()/mremap()
- arm64: Se validan las direcciones etiquetadas en access_ok() que se llama 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.
Usa 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, similar a aosp_coral_hwasan.
Para los usuarios familiarizados con AddressSanitizer, se eliminó mucha complejidad de compilación:
- No es necesario ejecutar make dos veces.
- Las compilaciones incrementales funcionan de inmediato.
- No es necesario escribir en la memoria flash los datos del usuario.
También se quitaron algunas restricciones de AddressSanitizer:
- Se admiten ejecutables estáticos.
- Puedes omitir la limpieza de cualquier objetivo que no sea libc. A diferencia de ASan, no es necesario que, si se limpia una biblioteca, también lo haga cualquier ejecutable que la vincule.
Se puede cambiar libremente entre imágenes HWASan y normales con la misma (o una versión posterior) de compilación. No es necesario limpiar 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 objetivos individuales
HWASan se puede habilitar por objetivo en una compilación normal (no limpia), siempre que libc.so
también esté limpia. 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 limpieza de libc habilita el etiquetado de asignaciones de memoria del montón en todo el sistema, así como la verificación de las etiquetas para las operaciones de memoria dentro de libc.so
. Esto puede detectar errores incluso en objetos binarios en los que no se habilitó HWASan si el acceso a la memoria defectuosa está 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.
Flashstation
Para fines de desarrollo, puedes escribir en la memoria flash una compilación de AOSP habilitada para HWASan en un dispositivo Pixel con bootloader desbloqueado con Flashstation. Selecciona el objetivo _hwasan, p.ej., aosp_flame_hwasan-userdebug. Consulta la documentación del NDK para HWASan para desarrolladores de apps y obtén más detalles.
Mejores seguimientos de pila
HWASan usa un desenredador rápido basado en el puntero 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 relajarte con el código administrado, configura HWASAN_OPTIONS=fast_unwind_on_malloc=0
en el entorno del proceso. Ten en cuenta que los seguimientos de pila de acceso a memoria incorrectos 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 ser muy intensiva en la CPU, según la carga.
Simbolización
Consulta Simbolización en "Cómo interpretar los informes de HWASan".
HWASan en apps
Al igual que AddressSanitizer, HWASan no puede ver el código Java, pero puede detectar errores en las bibliotecas JNI. Hasta Android 14, no se admitía la ejecución de apps de HWASan en un dispositivo que no fuera 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 LD_HWASAN=1
del archivo wrap.sh.
Consulta la documentación para desarrolladores de apps para obtener más detalles.