Google se compromete a promover la equidad racial para las comunidades negras. Ver cómo.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

AddressSanitizer

AddressSanitizer (ASan) es una herramienta rápida basada en compilador para detectar errores de memoria en código nativo.

ASan detecta:

  • Desbordamiento / desbordamiento del búfer de pila y pila
  • Uso del montón después de libre
  • Uso de la pila fuera del alcance
  • Doble libre / libre salvaje

ASan se ejecuta en ARM de 32 bits y 64 bits, más x86 y x86-64. La sobrecarga de la CPU de ASan es aproximadamente 2x, la sobrecarga del tamaño del código está entre 50% y 2x, y una sobrecarga de memoria grande (depende de sus patrones de asignación, pero del orden de 2x).

Android 10 y la rama maestra AOSP en AArch64 son compatibles con ASan acelerado por hardware (HWASan) , una herramienta similar con una sobrecarga de RAM más baja y un mayor rango de errores detectados. HWASan detecta el uso de la pila después del retorno, además de los errores detectados por ASan.

HWASan tiene una sobrecarga de CPU y tamaño de código similar, pero una sobrecarga de RAM mucho menor (15%). HWASan no es determinista. Solo hay 256 valores de etiqueta posibles, por lo que hay una probabilidad plana de 0.4% de perder cualquier error. HWASan no tiene las zonas rojas de tamaño limitado de ASan para detectar desbordamientos y la cuarentena de capacidad limitada para detectar el uso después de la liberación, por lo que no le importa a HWASan qué tan grande es el desbordamiento o cuánto tiempo hace que se desasignó la memoria. Esto hace que HWASan sea mejor que ASan. Puede leer más sobre el diseño de HWASan o sobre el uso de HWASan en Android .

ASan detecta desbordamientos de pila / globales además de desbordamientos de montón, y es rápido con una sobrecarga de memoria mínima.

Este documento describe cómo construir y ejecutar partes / todo Android con ASan. Si está creando una aplicación SDK / NDK con ASan, consulte en su lugar Address Sanitizer .

Desinfectar ejecutables individuales con ASan

Agregue LOCAL_SANITIZE:=address o sanitize: { address: true } a la regla de compilación para el ejecutable. Puede buscar ejemplos existentes en el código o encontrar otros desinfectantes disponibles.

Cuando se detecta un error, ASan imprime un informe detallado tanto en la salida estándar como en logcat y luego bloquea el proceso.

Desinfección de bibliotecas compartidas con ASan

Debido a la forma en que funciona ASan, una biblioteca construida con ASan solo puede ser utilizada por un ejecutable que esté construido con ASan.

Para desinfectar una biblioteca compartida que se utiliza en múltiples ejecutables, no todos los cuales están construidos con ASan, necesita dos copias de la biblioteca. La forma recomendada de hacer esto es agregar lo siguiente a Android.mk para el módulo en cuestión:

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

Esto coloca la biblioteca en /system/lib/asan lugar de /system/lib . Luego, ejecute su ejecutable con:

LD_LIBRARY_PATH=/system/lib/asan

Para los demonios del sistema, agregue lo siguiente a la sección correspondiente de /init.rc o /init.$device$.rc .

setenv LD_LIBRARY_PATH /system/lib/asan

Verifique que el proceso esté utilizando bibliotecas de /system/lib/asan cuando /system/lib/asan presente leyendo /proc/$PID/maps . Si no es así, es posible que deba deshabilitar SELinux:

adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID
# if it is a system service, or may be adb shell stop; adb shell start.

Mejores rastros de pila

ASan utiliza un desbobinador rápido basado en puntero de cuadro para registrar un seguimiento de pila para cada asignación de memoria y evento de desasignación en el programa. La mayoría de Android está construida sin punteros de cuadro. Como resultado, a menudo obtienes solo uno o dos cuadros significativos. Para solucionar esto, reconstruya la biblioteca con ASan (¡recomendado!) O con:

LOCAL_CFLAGS:=-fno-omit-frame-pointer
LOCAL_ARM_MODE:=arm

O establezca ASAN_OPTIONS=fast_unwind_on_malloc=0 en el entorno del proceso. Este último puede ser muy intensivo en CPU, dependiendo de la carga.

Simbolización

Inicialmente, los informes ASan contienen referencias a compensaciones en binarios y bibliotecas compartidas. Hay dos formas de obtener información de línea y archivo fuente:

  • Asegúrese de que el binario llvm-symbolizer esté presente en /system/bin . llvm-symbolizer está construido a partir de fuentes en third_party/llvm/tools/llvm-symbolizer .
  • Filtre el informe a través del script external/compiler-rt/lib/asan/scripts/symbolize.py .

El segundo enfoque puede proporcionar más datos (es decir, ubicaciones de file:line ) debido a la disponibilidad de bibliotecas simbolizadas en el host.

ASan en aplicaciones

ASan no puede ver el código Java, pero puede detectar errores en las bibliotecas JNI. Para eso, debe compilar el ejecutable con ASan, que en este caso es /system/bin/app_process( 32|64 ) . Esto habilita ASan en todas las aplicaciones en el dispositivo al mismo tiempo, lo cual es una carga pesada, pero un dispositivo con 2 GB de RAM debería ser capaz de manejar esto.

Agregue LOCAL_SANITIZE:=address a la app_process compilación app_process en frameworks/base/cmds/app_process . Ignore el objetivo app_process__asan en el mismo archivo por ahora (si todavía está allí en el momento en que lo leyó).

Edite la sección del service zygote archivo apropiado system/core/rootdir/init.zygote( 32|64 ).rc para agregar las siguientes líneas al bloque de líneas sangradas que contienen la class main , también sangrado por la misma cantidad:

    setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib
    setenv ASAN_OPTIONS allow_user_segv_handler=true

Compilación, sincronización de adb, arranque rápido de arranque flash y reinicio.

Usando la propiedad wrap

El enfoque en la sección anterior coloca a ASan en cada aplicación del sistema (en realidad, en cada descendiente del proceso Zygote). Es posible ejecutar solo una (o varias) aplicaciones con ASan, intercambiando algo de sobrecarga de memoria para un inicio más lento de la aplicación.

Esto se puede hacer iniciando su aplicación con el wrap. propiedad. El siguiente ejemplo ejecuta la aplicación Gmail en ASan:

adb root
adb shell setenforce 0  # disable SELinux
adb shell setprop wrap.com.google.android.gm "asanwrapper"

En este contexto, asanwrapper reescribe /system/bin/app_process en /system/bin/asan/app_process , que está construido con ASan. También agrega /system/lib/asan al comienzo de la ruta de búsqueda dinámica de la biblioteca. De esta forma, las bibliotecas instrumentadas con ASan de /system/lib/asan se prefieren a las bibliotecas normales en /system/lib cuando se ejecutan con asanwrapper .

Si se encuentra un error, la aplicación se bloquea y el informe se imprime en el registro.

SANITIZE_TARGET

Android 7.0 y superior incluye soporte para construir toda la plataforma Android con ASan a la vez. (Si está creando una versión superior a Android 9, HWASan es una mejor opción).

Ejecute los siguientes comandos en el mismo árbol de compilación.

make -j42
SANITIZE_TARGET=address make -j42

En este modo, userdata.img contiene bibliotecas adicionales y también debe actualizarse al dispositivo. Use la siguiente línea de comando:

fastboot flash userdata && fastboot flashall

Esto crea dos conjuntos de bibliotecas compartidas: normal en /system/lib (la primera invocación de creación) y ASan instrumentada en /data/asan/lib (la segunda invocación de creación). Los ejecutables de la segunda compilación sobrescriben los de la primera compilación. Los ejecutables instrumentados por ASan obtienen una ruta de búsqueda de biblioteca diferente que incluye /data/asan/lib antes /system/lib mediante el uso de /system/bin/linker_asan en PT_INTERP .

El sistema de compilación registra directorios de objetos intermedios cuando el valor $SANITIZE_TARGET ha cambiado. Esto obliga a reconstruir todos los objetivos al tiempo que conserva los binarios instalados en /system/lib .

Algunos objetivos no se pueden construir con ASan:

  • Ejecutables vinculados estáticamente
  • LOCAL_CLANG:=false objetivos LOCAL_CLANG:=false
  • LOCAL_SANITIZE:=false no se ASan'd para SANITIZE_TARGET=address

Ejecutables como estos se omiten en la compilación SANITIZE_TARGET , y la versión de la primera invocación se deja en /system/bin .

Bibliotecas como esta se construyen sin ASan. Pueden contener código ASan de las bibliotecas estáticas de las que dependen.

Documentación de apoyo