UndefinidoBehaviorSanitizer (UBSan) realiza instrumentación en tiempo de compilación para comprobar varios tipos de comportamiento indefinido. Si bien UBSan puede detectando muchos Errores de comportamiento no definido, Android admite lo siguiente:
- alineación
- booleano
- límites
- enum
- desbordamiento de float-cast
- float-divide-by-zero
- número entero-divide-por-cero
- atributo no nulo
- null
- return
- return-nonnull-attribute
- cambio-base
- exposición-exponente
- desbordamiento de número entero con signo
- inaccesible
- desbordamiento de números enteros sin signo
- delimitado a vla
desbordamiento de números enteros sin firma, mientras que no es técnicamente definido se incluye en sanitizer y se usa en muchos módulos de Android, incluidos los componentes de mediaserver, para eliminar cualquier desbordamiento latente de enteros vulnerabilidades.
Implementación
En el sistema de compilación de Android, puedes habilitar UBSan de manera global o local. Para habilitar UBSan globalmente, establece SANITIZE_TARGET en Android.mk. Para habilitar UBSan en una por módulo, configura LOCAL_SANITIZE y especifica los comportamientos indefinidos que que quieras buscar en Android.mk. Por ejemplo:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0 LOCAL_SRC_FILES:= sanitizer-status.c LOCAL_MODULE:= sanitizer-status LOCAL_SANITIZE := alignment bounds null unreachable integer LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer include $(BUILD_EXECUTABLE)
Y la configuración de plano equivalente (Android.bp):
cc_binary { cflags: [ "-std=c11", "-Wall", "-Werror", "-O0", ], srcs: ["sanitizer-status.c"], name: "sanitizer-status", sanitize: { misc_undefined: [ "alignment", "bounds", "null", "unreachable", "integer", ], diag: { misc_undefined: [ "alignment", "bounds", "null", "unreachable", "integer", ], }, }, }
Atajos de UBSan
Android también tiene dos combinaciones de teclas: integer
y
default-ub
, para habilitar un conjunto de desinfectantes al mismo tiempo. número entero
habilita integer-divide-by-zero
,
signed-integer-overflow
y unsigned-integer-overflow
.
default-ub
habilita las verificaciones que tienen un compilador mínimo.
problemas de rendimiento: bool, integer-divide-by-zero, return,
returns-nonnull-attribute, shift-exponent, unreachable and vla-bound
. El
puede usarse con SANITIZE_TARGET y LOCAL_SANITIZE,
mientras que default-ub solo puede usarse con SANITIZE_TARGET.
Mejores informes de errores
La implementación de UBSan predeterminada de Android invoca una función especificada cuando se encuentra un comportamiento indefinido. De forma predeterminada, esta función está anulada. Sin embargo, a partir de octubre de 2016, UBSan en Android tiene una biblioteca de tiempo de ejecución opcional que brinda informes de errores más detallados, incluido el tipo de comportamiento indefinido archivos y la información de la línea del código fuente. Para habilitar este error, sigue estos pasos: Los informes con verificaciones de números enteros agregan lo siguiente a un archivo Android.mk:
LOCAL_SANITIZE:=integer LOCAL_SANITIZE_DIAG:=integer
El valor LOCAL_SANITIZE habilita el limpiador durante la compilación. LOCAL_SANITIZE_DIAG activa el modo de diagnóstico para el desinfectante especificado. Sí es posible establecer LOCAL_SANITIZE y LOCAL_SANITIZE_DIAG en valores diferentes, pero solo están habilitadas las comprobaciones de LOCAL_SANITIZE. Si una comprobación no se especifica en LOCAL_SANITIZE, pero se especificó en LOCAL_SANITIZE_DIAG, la marca no está habilitada y no se entregan mensajes de diagnóstico.
A continuación, se muestra un ejemplo de la información proporcionada por la biblioteca del entorno de ejecución de UBSan:
pixel-xl:/ # sanitizer-status ubsan sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')
Limpieza de desbordamiento de números enteros
Los desbordamientos no deseados de números enteros pueden causar daños en la memoria o en la información revelar vulnerabilidades en variables asociadas con accesos a la memoria o asignaciones de memoria. Para combatirlo, agregamos funciones de UndefinidoBehaviorSanitizer (UBSan) con y sin firmas, limpiadores de desbordamiento de enteros con firma para endurecer el framework multimedia en Android 7.0. En Android 9, expandido UBSan para abarcar más componentes y una mejor compatibilidad con el sistema de compilación
Se diseñó para agregar comprobaciones de aritmética instrucciones de operaciones, que podrían desbordamiento, para anular de forma segura un proceso si se produce un desbordamiento. Estos limpiadores pueden mitigar una clase completa de daños en la memoria y vulnerabilidades de divulgación de información en las que la causa raíz sea un número desbordamiento, como la vulnerabilidad original de Stagefright.
Ejemplos y fuente
El compilador proporciona la limpieza de desbordamiento de enteros (IntSan) y agrega
la instrumentación en el objeto binario durante el tiempo de compilación para detectar la aritmética
se desborde. Se habilita de forma predeterminada en varios componentes de la
plataforma, por ejemplo,
/platform/external/libnl/Android.bp
Implementación
IntSan usa los limpiadores de desbordamiento de enteros firmados y sin firma de UBSan. Esta la mitigación está habilitada de a un nivel por módulo. Ayuda a mantener los componentes críticos de Android y no deben inhabilitarse.
Te recomendamos que habilites la limpieza de desbordamiento de enteros para obtener o los componentes de la solución. Los candidatos ideales son código nativo o código nativo con privilegios analiza las entradas de usuarios que no son de confianza. Hay una pequeña sobrecarga de rendimiento asociada con el limpiador que depende del uso del código y de la prevalencia operaciones aritméticas. Espera un pequeño porcentaje de sobrecarga y prueba si el rendimiento es un problema.
Compatibilidad con IntSan en archivos makefile
Para habilitar IntSan en un makefile, agrega lo siguiente:
LOCAL_SANITIZE := integer_overflow # Optional features LOCAL_SANITIZE_DIAG := integer_overflow LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
LOCAL_SANITIZE
toma una lista de limpiadores separados por comas.integer_overflow
es un conjunto de opciones empaquetadas previamente para los limpiadores de desbordamiento de enteros firmados y sin firma con un predeterminado LISTA DE BLOQUEOS.LOCAL_SANITIZE_DIAG
activa el modo de diagnóstico para el desinfectantes. Usa el modo de diagnóstico solo durante la prueba, ya que esto no ante desbordamientos, lo que anula por completo la ventaja de seguridad del la mitigación del problema. Consulta Solución de problemas. para obtener más detalles.LOCAL_SANITIZE_BLOCKLIST
te permite especificar una BLOCKLIST. para evitar que se limpien las funciones y los archivos de origen. Consulta Solución de problemas para obtener más más detalles.
Si quieres tener un control más detallado, habilita los desinfectantes de forma individual mediante uno o ambas marcas:
LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow
Compatibilidad con IntSan en archivos de planos
Para habilitar la limpieza de desbordamiento de enteros en un archivo de plano técnico, como
/platform/external/libnl/Android.bp
:
agregar:
sanitize: { integer_overflow: true, diag: { integer_overflow: true, }, BLOCKLIST: "modulename_BLOCKLIST.txt", },
Al igual que con los archivos make, la propiedad integer_overflow
es un paquete
conjunto de opciones para el desbordamiento de enteros individual con y sin firma
desinfectantes con una configuración
LISTA DE BLOQUEOS
El conjunto de propiedades diag
habilita el modo de diagnóstico de la
desinfectantes. Usa el modo de diagnóstico solo durante las pruebas. El modo de diagnóstico no
ante desbordamientos, lo que anula por completo la ventaja de seguridad de la
mitigación en compilaciones de usuarios. Consulta Solución de problemas para obtener más detalles.
La propiedad BLOCKLIST
permite especificar un archivo BLOCKLIST.
que permite que los desarrolladores eviten que las funciones y los archivos de origen queden
y los datos se desinfectan. Consulta Solución de problemas para
detalles adicionales.
Para habilitar los limpiadores de manera individual, usa lo siguiente:
sanitize: { misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"], diag: { misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow",], }, BLOCKLIST: "modulename_BLOCKLIST.txt", },
Solución de problemas
Si habilitas la limpieza de desbordamiento de números enteros en nuevos componentes o dependes de plataformas que tuvieron limpieza de desbordamiento de enteros, puedes encontrar problemas con desbordamientos de enteros benignos que provocan anulaciones. Deberías probar componentes con limpieza habilitada para garantizar que puedan aparecer desbordamientos benignos.
Para buscar anulaciones provocadas por la limpieza en compilaciones de usuarios, busca
SIGABRT
falla con mensajes de anulación que indican que se detectó un desbordamiento.
por UBSan, por ejemplo:
pid: ###, tid: ###, name: Binder:### >>> /system/bin/surfaceflinger <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'ubsan: sub-overflow'
El seguimiento de pila debe incluir la función que causa la anulación. Sin embargo, los desbordamientos que ocurren en las funciones intercaladas pueden no ser evidentes en el seguimiento de pila.
Para determinar la causa raíz con mayor facilidad, habilita el diagnóstico en la biblioteca que desencadena la anulación e intenta reproducir el error. Con el diagnóstico habilitado, no se anulará el proceso, sino que sigan ejecutándose. No anular ayuda a maximizar el número de desbordamientos benignos en una una ruta de ejecución específica sin tener que volver a compilar después de corregir cada error. El diagnóstico produce un mensaje de error que incluye el número de línea y la fuente archivo que provoca la anulación:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
Una vez que se encuentre la operación aritmética problemática, asegúrate de que el desbordamiento Es benigno y está previsto (p.ej., no tiene consecuencias para la seguridad). Puedes abordar las sanitizer anulan de las siguientes maneras:
- Cómo refactorizar el código para evitar el desbordamiento (ejemplo)
- Desbordamiento explícito a través del __builtin_*_overflow de Clang funciones (ejemplo)
- Especifica el atributo
no_sanitize
para inhabilitar la limpieza en la función (ejemplo) - Inhabilita la limpieza de una función o un archivo de origen mediante un archivo BLOCKLIST (ejemplo)
Debes usar la solución más detallada posible. Por ejemplo, una gran con muchas operaciones aritméticas y una sola operación desbordante se debe refactorizar la operación única en lugar de toda la función Bloqueada en la lista de entidades bloqueadas
Entre los patrones comunes que pueden provocar desbordamientos benignos, se incluyen los siguientes:
- Implícito conversiones en las que se produce un desbordamiento sin firma antes de que se transmita a un tipo con firma (ejemplo)
- Eliminación de listas vinculadas que disminuye el índice del bucle cuando se borra (ejemplo)
- La asignación de un tipo sin firma a -1 en lugar de especificar el valor máximo real (ejemplo)
- Bucles que disminuyen un número entero sin firma en la condición (ejemplo, ejemplo)
Se recomienda que los desarrolladores aseguren que los casos en los que el desinfectante detecte desbordamiento que indica que es realmente benigno sin efectos secundarios no deseados ni seguridad implicaciones antes de inhabilitar la limpieza.
Inhabilitar IntSan
Puedes inhabilitar IntSan con BLOCKLISTs o atributos de función. Inhabilita con moderación y solo cuando la refactorización del código sea injustificada o si hay una sobrecarga de rendimiento problemática.
Consulta la documentación de Clang ascendente para obtener más información sobre cómo inhabilitar IntSan con la función atributos y el archivo BLOCKLIST de formato. La lista de bloques de bloqueo debe tener el alcance del desinfectante específico. usar nombres de sección que especifiquen el limpiador de destino para evitar que otras desinfectantes.
Validación
Actualmente, no hay una prueba de CTS específica para la limpieza de desbordamiento de enteros. En su lugar, asegúrate de que las pruebas del CTS sean exitosas con o sin IntSan habilitado para realizar la verificación. para que no afecte al dispositivo.
Limpieza de límites
BoundsSanitizer (BoundSan) agrega instrumentación a objetos binarios para insertar límites comprobaciones de accesos a arrays. Estas comprobaciones se agregan si el compilador no puede demostrar en el tiempo de compilación que el acceso será seguro y si el tamaño del array en el tiempo de ejecución, a fin de poder verificarlos. Android 10 implementa BoundSan en Bluetooth y códecs El compilador proporciona BoundSan y es habilitado por de forma predeterminada en varios componentes de la plataforma.
Implementación
BoundSan usa UBSan's suavizante de límites. Esta mitigación se habilita de a un nivel por módulo. Ayuda mantienen seguros los componentes esenciales de Android y no deben inhabilitarse.
Te recomendamos que habilites BoundSan para componentes adicionales. Los candidatos ideales son código nativo con privilegios o código nativo complejo que analiza de usuarios que no son de confianza. La sobrecarga de rendimiento asociada con la habilitación de BoundSan depende de la cantidad de accesos a arrays que no sean seguros. Espera un un pequeño porcentaje de sobrecarga y prueba si el rendimiento es un problema.
Habilita BoundSan en los archivos de planos
BoundSan se puede habilitar en los archivos de esquemas si agregas "bounds"
.
a la propiedad de limpieza de misc_undefined
para objetos binarios y bibliotecas
módulos:
sanitize: { misc_undefined: ["bounds"], diag: { misc_undefined: ["bounds"], }, BLOCKLIST: "modulename_BLOCKLIST.txt",
diagnóstico
La propiedad diag
habilita el modo de diagnóstico para los limpiadores.
Usa el modo de diagnóstico solo durante las pruebas. El modo de diagnóstico no se anula en
desbordamiento, lo que anula la ventaja de seguridad de la mitigación y conlleva
una sobrecarga de rendimiento mayor, por lo que no se recomienda para compilaciones de producción.
LISTA DE BLOQUEOS
La propiedad BLOCKLIST
permite especificar una BLOCKLIST.
que los desarrolladores pueden usar para evitar que se borren las funciones y los archivos de origen
y los datos se desinfectan. Usa esta propiedad solo si el rendimiento es un problema
archivos/funciones contribuyen de forma sustancial. Audita estos archivos o funciones de forma manual
para garantizar que los accesos a los arrays sean seguros. Consulta Solución de problemas para obtener más
más detalles.
Habilita BoundSan en archivos makefile
BoundSan se puede habilitar en los archivos makefile agregando "bounds"
.
a la variable LOCAL_SANITIZE
para los módulos binarios y de biblioteca:
LOCAL_SANITIZE := bounds # Optional features LOCAL_SANITIZE_DIAG := bounds LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
LOCAL_SANITIZE
acepta una lista de limpiadores separados por un elemento
coma.
LOCAL_SANITIZE_DIAG
activa el modo de diagnóstico. Usar diagnósticos
solo durante las pruebas. El modo de diagnóstico no se anula cuando hay desbordamientos, lo que
niega la ventaja de seguridad de la mitigación y conlleva una mayor
la sobrecarga de rendimiento, por lo que no se recomienda para compilaciones de producción.
LOCAL_SANITIZE_BLOCKLIST
permite especificar una BLOCKLIST.
que permite que los desarrolladores impidan que se borren las funciones y los archivos de origen
y los datos se desinfectan. Usa esta propiedad solo si el rendimiento es un problema
archivos/funciones contribuyen de forma sustancial. Audita estos archivos o funciones de forma manual
para garantizar que los accesos a los arrays sean seguros. Consulta Solución de problemas para obtener más
más detalles.
Inhabilitar BoundSan
Puedes inhabilitar BoundSan en las funciones y los archivos de origen con BLOCKLISTs o atributos de la función. Es mejor mantener BoundSan habilitado, por lo que solo inhabilitarlo si la función o el archivo crea una gran cantidad de sobrecarga de rendimiento, y la la fuente se revisó manualmente.
Para obtener más información sobre cómo inhabilitar BoundSan con la función atributos y el archivo BLOCKLIST formateo, consulta la documentación de LLVM de Clang. Define el alcance de BLOCKLISTa a un desinfectante específico usando nombres de sección que especifiquen desinfectante objetivo para evitar el impacto de otros desinfectantes.
Validación
No hay una prueba de CTS específica para BoundSan. En su lugar, asegúrate de que el CTS las pruebas se aprueban, con o sin BoundSan habilitado para verificar que no tenga ningún impacto el dispositivo.
Solución de problemas
Prueba rigurosamente los componentes luego de habilitar BoundSan para garantizar que cualquier se abordan los accesos fuera de los límites no detectados.
Los errores BoundSan pueden identificarse fácilmente, ya que incluyen lo siguiente: mensaje de anulación de tombstone:
pid: ###, tid: ###, name: Binder:### >>> /system/bin/foobar <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'ubsan: out-of-bounds'
Cuando se ejecuta en modo de diagnóstico, el archivo de origen, el número de línea y el índice
valor se imprimen en logcat
. De forma predeterminada, este modo no
arroja un mensaje anulado. Revisa logcat
para ver si hay alguno
errores.
external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'