UndefinidoBehaviorSanitizer

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]'