Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Formato de archivo APEX

El formato de contenedor de Android Pony EXpress (APEX) se introdujo en Android 10 y se usa en el flujo de instalación para los módulos del sistema de nivel inferior. Este formato facilita las actualizaciones de los componentes del sistema que no encajan en el modelo de aplicación estándar de Android. Algunos componentes de ejemplo son los servicios nativos y bibliotecas, capas de abstracción de hardware ( HAL ), tiempo de ejecución ( ART ), y bibliotecas de clases.

El término "APEX" también puede referirse a un archivo APEX.

Fondo

Aunque Android admite actualizaciones de módulos que se ajustan al modelo de aplicación estándar (por ejemplo, servicios, actividades) a través de aplicaciones de instalación de paquetes (como la aplicación Google Play Store), el uso de un modelo similar para componentes de sistema operativo de nivel inferior tiene los siguientes inconvenientes:

  • Los módulos basados ​​en APK no se pueden usar al principio de la secuencia de inicio. El administrador de paquetes es el repositorio central de información sobre las aplicaciones y solo se puede iniciar desde el administrador de actividades, que está listo en una etapa posterior del procedimiento de arranque.
  • El formato APK (particularmente el manifiesto) está diseñado para aplicaciones de Android y los módulos del sistema no siempre son una buena opción.

Diseño

Esta sección describe el diseño de alto nivel del formato de archivo APEX y el administrador APEX, que es un servicio que administra archivos APEX.

Para obtener más información sobre por qué se eligió este diseño para APEX, ver alternativas consideradas en el desarrollo de APEX .

Formato APEX

Este es el formato de un archivo APEX.

Formato de archivo APEX

Formato de archivo de la Figura 1. APEX

En el nivel superior, un archivo APEX es un archivo zip en el que los archivos se almacenan sin comprimir y ubicados en límites de 4 KB.

Los cuatro archivos de un archivo APEX son:

  • apex_manifest.json
  • AndroidManifest.xml
  • apex_payload.img
  • apex_pubkey

El apex_manifest.json archivo contiene el nombre del paquete y la versión, que identifican un archivo de APEX.

El AndroidManifest.xml archivo permite que el archivo de APEX para utilizar las herramientas de APK-relacionados y la infraestructura, como ADB, PackageManager y aplicaciones de instalador de paquete (como Play Store). Por ejemplo, el archivo de APEX puede utilizar una herramienta existente como aapt para inspeccionar los metadatos básicos del archivo. El archivo contiene información sobre el nombre y la versión del paquete. Esta información es generalmente también disponible en apex_manifest.json .

apex_manifest.json se recomienda más que AndroidManifest.xml para el nuevo código y sistemas que tienen que ver con APEX. AndroidManifest.xml podría contener información de orientación adicional que puede ser utilizado por las herramientas de publicación de aplicaciones existentes.

apex_payload.img es una imagen del sistema de archivos ext4 respaldado por dm-Verity. La imagen se monta en tiempo de ejecución a través de un dispositivo de bucle invertido. En concreto, el árbol de hash y el bloque de metadatos se crean utilizando el libavb biblioteca. La carga útil del sistema de archivos no se analiza (porque la imagen debe poder montarse en su lugar). Archivos normales se incluyen dentro de la apex_payload.img archivo.

apex_pubkey es la clave pública utilizada para firmar la imagen del sistema de archivos. En tiempo de ejecución, esta clave asegura que el APEX descargado esté firmado con la misma entidad que firma el mismo APEX en las particiones integradas.

Gerente APEX

El director de APEX (o apexd ) es un proceso nativo independiente responsable de la verificación, instalación y desinstalación de archivos APEX. Este proceso se inicia y está listo al principio de la secuencia de inicio. APEX archivos son normalmente pre-instalado en el dispositivo bajo /system/apex . El administrador de APEX utiliza estos paquetes de forma predeterminada si no hay actualizaciones disponibles.

La secuencia de actualización de una APEX utiliza la clase PackageManager y es como sigue.

  1. Un archivo APEX se descarga a través de una aplicación de instalación de paquetes, ADB u otra fuente.
  2. El administrador de paquetes inicia el procedimiento de instalación. Al reconocer que el archivo es un APEX, el administrador de paquetes transfiere el control al administrador de APEX.
  3. El administrador de APEX verifica el archivo APEX.
  4. Si se verifica el archivo APEX, la base de datos interna del administrador APEX se actualiza para reflejar que el archivo APEX se activa en el próximo arranque.
  5. El solicitante de la instalación recibe una transmisión tras la verificación exitosa del paquete.
  6. Para continuar con la instalación, se debe reiniciar el sistema.
  7. En el siguiente arranque, el administrador APEX se inicia, lee la base de datos interna y hace lo siguiente para cada archivo APEX enumerado:

    1. Verifica el archivo APEX.
    2. Crea un dispositivo de bucle invertido a partir del archivo APEX.
    3. Crea un dispositivo de bloque de mapeador de dispositivos en la parte superior del dispositivo de bucle invertido.
    4. Se monta el dispositivo de bloque mapeador de dispositivos en un camino único (por ejemplo, /apex/ name @ ver ).

Cuando se montan todos los archivos APEX enumerados en la base de datos interna, el administrador APEX proporciona un servicio de enlace para que otros componentes del sistema consulten información sobre los archivos APEX instalados. Por ejemplo, los otros componentes del sistema pueden consultar la lista de archivos APEX instalados en el dispositivo o consultar la ruta exacta donde se monta un APEX específico, para que se pueda acceder a los archivos.

Los archivos APEX son archivos APK

APEX archivos son archivos APK válidos porque están firmados zip archivos (utilizando el esquema de firma APK) que contiene un AndroidManifest.xml archivo. Esto permite que los archivos APEX usen la infraestructura para archivos APK, como una aplicación de instalación de paquetes, la utilidad de firma y el administrador de paquetes.

El AndroidManifest.xml archivo dentro de un archivo de APEX es mínima, que consiste en el paquete name , versionCode , y opcional targetSdkVersion , minSdkVersion y maxSdkVersion de grano fino de orientación. Esta información permite que los archivos APEX se envíen a través de los canales existentes, como las aplicaciones de instalación de paquetes y ADB.

Tipos de archivos compatibles

El formato APEX admite estos tipos de archivos:

  • Libs compartidas nativas
  • Ejecutables nativos
  • Archivos JAR
  • Archivos de información
  • Archivos de configuración

Esto no significa que APEX pueda actualizar todos estos tipos de archivos. La posibilidad de actualizar un tipo de archivo depende de la plataforma y de la estabilidad de las definiciones de las interfaces para los tipos de archivos.

Firma

Los archivos APEX se firman de dos formas. En primer lugar, la apex_payload.img (en concreto, el descriptor vbmeta anexa a apex_payload.img ) archivo está firmado con una clave. Entonces, toda la APEX se ha firmado con la v3 esquema de firma APK . En este proceso se utilizan dos claves diferentes.

En el lado del dispositivo, se instala una clave pública correspondiente a la clave privada utilizada para firmar el descriptor vbmeta. El administrador de APEX utiliza la clave pública para verificar los APEX que se solicita instalar. Cada APEX debe estar firmado con claves diferentes y se aplica tanto en el momento de la compilación como en el tiempo de ejecución.

APEX en particiones integradas

APEX archivos pueden estar ubicados en como una función de las particiones /system . La partición ya está sobre dm-verity, por lo que los archivos APEX se montan directamente sobre el dispositivo de bucle invertido.

Si un APEX está presente en una partición incorporada, el APEX se puede actualizar proporcionando un paquete APEX con el mismo nombre de paquete y un código de versión mayor o igual. El nuevo APEX se almacena en /data y, de forma similar a APK, la versión recién instalada la versión sombras ya presentes en la partición incorporado. Pero a diferencia de los APK, la versión recién instalada de APEX solo se activa después de reiniciar.

Requisitos del kernel

Para admitir los módulos de la línea principal APEX en un dispositivo Android, se requieren las siguientes características del kernel de Linux: el controlador de bucle invertido y dm-verity. El controlador de bucle invertido monta la imagen del sistema de archivos en un módulo APEX y dm-verity verifica el módulo APEX.

El rendimiento del controlador de bucle invertido y dm-verity es importante para lograr un buen rendimiento del sistema cuando se utilizan módulos APEX.

Versiones de kernel compatibles

Los módulos de la línea principal APEX son compatibles con dispositivos que utilizan versiones de kernel 4.4 o superiores. Los dispositivos nuevos que se inician con Android 10 o superior deben usar la versión 4.9 o superior del kernel para admitir módulos APEX.

Parches de kernel necesarios

Los parches de kernel necesarios para admitir módulos APEX se incluyen en el árbol común de Android. Para que los parches sean compatibles con APEX, utilice la última versión del árbol común de Android.

Kernel versión 4.4

Esta versión solo es compatible con dispositivos que se actualizan de Android 9 a Android 10 y desean admitir módulos APEX. Para obtener los parches necesarios, una baja fusión del android-4.4 es muy recomendable rama. La siguiente es una lista de los parches individuales necesarios para la versión 4.4 del kernel.

  • UPSTREAM: loop: añadir ioctl para el cambio de tamaño de bloque lógico ( 4.4 )
  • Backport: bloque / bucle: SET hw_sectors ( 4,4 )
  • CONTRA LA CORRIENTE: loop: Agregar LOOP_SET_BLOCK_SIZE en compat ioctl ( 4.4 )
  • ANDROID: mnt: next_descendent Fix ( 4.4 )
  • ANDROID: mnt: volver a montar debe ser propagado a los esclavos de los esclavos ( 4.4 )
  • ANDROID: mnt: Propagar volver a montar correctamente ( 4.4 )
  • Revertir "ANDROID: dm Verity: añadir un tamaño mínimo de captura previa" ( 4.4 )
  • UPSTREAM: loop: cachés gota Si el desplazamiento o block_size se cambian ( 4,4 )

Versiones de kernel 4.9 / 4.14 / 4.19

Para obtener los parches necesarios para las versiones del kernel 4.9 / 4.14 / 4.19, abajo de combinación del android-common rama.

Opciones de configuración del kernel necesarias

La siguiente lista muestra los requisitos de configuración base para admitir módulos APEX que se introdujeron en Android 10. Los elementos con un asterisco (*) son requisitos existentes de Android 9 y versiones anteriores.

(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices)
CONFIG_BLK_DEV_LOOP=Y # for loop device support
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices
(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity
(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity
CONFIG_DM_VERITY=Y # DM-verity support

Requisitos de los parámetros de la línea de comandos del kernel

Para admitir APEX, asegúrese de que los parámetros de la línea de comandos del kernel cumplan con los siguientes requisitos:

  • loop.max_loop no debe estar
  • loop.max_part debe ser <= 8

Construyendo un APEX

Esta sección describe cómo construir un APEX usando el sistema de compilación de Android. El siguiente es un ejemplo de Android.bp para una llamada APEX apex.test .

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    // libc.so and libcutils.so are included in the apex
    native_shared_libs: ["libc", "libcutils"],
    binaries: ["vold"],
    java_libs: ["core-all"],
    prebuilts: ["my_prebuilt"],
    compile_multilib: "both",
    key: "apex.test.key",
    certificate: "platform",
}

apex_manifest.json ejemplo:

{
  "name": "com.android.example.apex",
  "version": 1
}

file_contexts ejemplo:

(/.*)?           u:object_r:system_file:s0
/sub(/.*)?       u:object_r:sub_file:s0
/sub/file3       u:object_r:file3_file:s0

Tipos de archivos y ubicaciones en APEX

Tipo de archivo Ubicación en APEX
Bibliotecas compartidas /lib y /lib64 ( /lib/arm para el brazo traducido en x86)
Ejecutables /bin
Bibliotecas Java /javalib
Preconstruidos /etc

Dependencias transitivas

Los archivos APEX incluyen automáticamente dependencias transitivas de libs o ejecutables compartidos nativos. Por ejemplo, si libFoo depende de libBar , las dos bibliotecas se incluyen, cuando sólo libFoo aparece en la native_shared_libs propiedad.

Manejo de múltiples ABI

Instalar el native_shared_libs propiedad para ambas interfaces de aplicación binarios primaria y secundaria (Abis) del dispositivo. Si un APEX apunta a dispositivos con una única ABI (es decir, solo 32 bits o solo 64 bits), solo se instalan las bibliotecas con la ABI correspondiente.

Instalar el binaries propiedad sólo para el ABI principal del dispositivo como se describe a continuación:

  • Si el dispositivo es solo de 32 bits, solo se instala la variante de 32 bits del binario.
  • Si el dispositivo es solo de 64 bits, solo se instala la variante de 64 bits del binario.

Para agregar un control detallado sobre los ABIs de las bibliotecas y binarios nativos, utilice el multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] propiedades.

  • first : Emparejamientos el primario ABI del dispositivo. Este es el valor predeterminado para los binarios.
  • lib32 : Emparejamientos el 32-bit ABI del dispositivo, si es compatible.
  • lib64 : Emparejamientos el 64-bit ABI del dispositivo, apoyó.
  • prefer32 : Emparejamientos el 32-bit ABI del dispositivo, si es compatible. Si no se admite la ABI de 32 bits, coincide con la ABI de 64 bits.
  • both : Partidos ambos ABIs. Este es el valor predeterminado para native_shared_libraries .

Los java , libraries , y prebuilts propiedades son ABI-agnóstico.

Este ejemplo es para un dispositivo que admite 32/64 y no prefiere 32:

apex {
    // other properties are omitted
    native_shared_libs: ["libFoo"], // installed for 32 and 64
    binaries: ["exec1"], // installed for 64, but not for 32
    multilib: {
        first: {
            native_shared_libs: ["libBar"], // installed for 64, but not for 32
            binaries: ["exec2"], // same as binaries without multilib.first
        },
        both: {
            native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
            binaries: ["exec3"], // installed for 32 and 64
        },
        prefer32: {
            native_shared_libs: ["libX"], // installed for 32, but not for 64
        },
        lib64: {
            native_shared_libs: ["libY"], // installed for 64, but not for 32
        },
    },
}

firma de vbmeta

Firma cada APEX con diferentes claves. Cuando se requiere una nueva clave, crear un par de claves pública y privada y crea un apex_key módulo. Usar la key propiedad para firmar el APEX con la tecla. La clave pública se incluye automáticamente en el APEX con el nombre avb_pubkey .

# create an rsa key pair
openssl genrsa -out foo.pem 4096

# extract the public key from the key pair
avbtool extract_public_key --key foo.pem --output foo.avbpubkey

# in Android.bp
apex_key {
    name: "apex.test.key",
    public_key: "foo.avbpubkey",
    private_key: "foo.pem",
}

En el ejemplo anterior, el nombre de la clave pública ( foo ) se convierte en el ID de la clave. El ID de la clave utilizada para firmar un APEX se escribe en el APEX. En tiempo de ejecución, apexd verifica la APEX usando una clave pública con el mismo ID en el dispositivo.

Firma ZIP

Firme APEX de la misma manera que firma APK. Firme APEX dos veces; una vez para el sistema de archivos de mini ( apex_payload.img archivo) y una vez para todo el archivo.

Para firmar un vértice en el nivel de archivo, establezca el certificate propiedad en una de estas tres maneras:

  • No ajuste: Si no se establece ningún valor, el APEX está firmado con el certificado ubicado en PRODUCT_DEFAULT_DEV_CERTIFICATE . Si no hay ningún indicador está establecido, los valores por defecto Path to build/target/product/security/testkey .
  • <name> : La APEX se firmó con el <name> certificado en el mismo directorio que PRODUCT_DEFAULT_DEV_CERTIFICATE .
  • :<name> : El APEX está firmado con el certificado que se define por el módulo de Soong llamado <name> . El módulo de certificado se puede definir de la siguiente manera.
android_app_certificate {
    name: "my_key_name",
    certificate: "dir/cert",
    // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key)
}

Instalación de un APEX

Para instalar un APEX, use ADB.

adb install apex_file_name
adb reboot

Usando un APEX

Después del reinicio, el APEX se monta en la /apex/<apex_name>@<version> directorio. Se pueden montar varias versiones del mismo APEX al mismo tiempo. Entre las rutas de acceso, la que corresponde a la versión más reciente es bind-montado en /apex/<apex_name> .

Los clientes pueden utilizar la ruta montada en enlace para leer o ejecutar archivos desde APEX.

Los APEX se utilizan normalmente de la siguiente manera:

  1. Un OEM o del ODM precargas un vértice bajo /system/apex cuando se envía el dispositivo.
  2. Los archivos de la APEX se accede a través del /apex/<apex_name>/ ruta.
  3. Cuando una versión actualizada de la APEX se instala en /data/apex , los puntos de ruta a la nueva APEX al iniciar el sistema.

Actualizar un servicio con un APEX

Para actualizar un servicio usando un APEX:

  1. Marque el servicio en la partición del sistema como actualizable. Añadir la opción updatable a la definición del servicio.

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. Crear un nuevo .rc archivo para el servicio actualizado. Utilice la override la opción de redefinir el servicio existente.

    /apex/my.apex@1/etc/init.rc:
    
    service myservice /apex/my.apex@1/bin/myservice
        class core
        user system
        ...
        override
    

Definiciones de servicios sólo se pueden definir en el .rc de archivo de una APEX. Los activadores de acción no son compatibles con APEX.

Si un servicio marcado como actualizable comienza antes de que se activen los APEX, el inicio se retrasa hasta que se completa la activación de los APEX.

Configuración del sistema para admitir actualizaciones APEX

Establezca la propiedad siguiente sistema para true para soportar actualizaciones de archivos de APEX.

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

o solo

<device.mk>:

$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)

APEX aplanado

Para los dispositivos heredados, a veces es imposible o inviable actualizar el kernel anterior para que sea totalmente compatible con APEX. Por ejemplo, el núcleo podría haber sido construido sin CONFIG_BLK_DEV_LOOP=Y , lo que es crucial para el montaje de la imagen del sistema de archivos dentro de un ápice.

APEX aplanado es un APEX especialmente construido que se puede activar en dispositivos con un kernel heredado. Los archivos en un APEX plano se instalan directamente en un directorio en la partición incorporada. Por ejemplo, lib/libFoo.so en un aplanado APEX my.apex está instalado para /system/apex/my.apex/lib/libFoo.so .

La activación de un APEX aplanado no implica el dispositivo de bucle. Todo el directorio /system/apex/my.apex está directamente bind-montado en /apex/name@ver .

Los APEX aplanados no se pueden actualizar descargando versiones actualizadas de los APEX de la red porque los APEX descargados no se pueden aplanar. Los APEX aplanados solo se pueden actualizar a través de una OTA normal.

APEX aplanado es la configuración predeterminada. Esto significa que todos los APEX están acoplados de forma predeterminada a menos que configure explícitamente su dispositivo para crear APEX no acoplados para admitir actualizaciones de APEX (como se explicó anteriormente).

NO se admite la mezcla de APEX aplanados y no aplanados en un dispositivo. Los APEX de un dispositivo deben estar totalmente aplanados o no aplanados. Esto es especialmente importante al enviar preconstrucciones APEX firmadas previamente para proyectos como Mainline. Los APEX que no están presignados (es decir, construidos a partir de la fuente) también deben estar no aplanados y firmados con las claves adecuadas. El dispositivo debe heredar de updatable_apex.mk como se explica en la actualización de un servicio con un ápice .

APEX comprimidos

Android 12 y versiones posteriores cuentan con compresión APEX para reducir el impacto de almacenamiento de los paquetes APEX actualizables. Después de instalar una actualización de un APEX, aunque su versión preinstalada ya no se usa, todavía ocupa la misma cantidad de espacio. Ese espacio ocupado sigue sin estar disponible.

APEX compresión reduce al mínimo este impacto de almacenamiento mediante el uso de un conjunto altamente comprimido de archivos de APEX en particiones de sólo lectura (como el /system partición). Android 12 y versiones posteriores usan un algoritmo de compresión zip DEFLATE.

La compresión no proporciona optimización a lo siguiente:

  • Bootstrap APEX que deben montarse muy temprano en la secuencia de inicio.

  • APEX no actualizables. La compresión es sólo es beneficioso si una versión actualizada de un APEX está instalado en el /data de la partición. Una lista completa de los vértices actualizables está disponible en el los componentes del sistema modular página.

  • Libs dinámicos compartidos APEX. Desde apexd siempre activa ambas versiones de dichos vértices (pre-instalado y actualizado), comprimirlos no añade valor.

Formato de archivo APEX comprimido

Este es el formato de un archivo APEX comprimido.

Diagram shows the format of a compressed APEX file

Formato de archivo comprimido Figura 2. APEX

En el nivel superior, un archivo APEX comprimido es un archivo zip que contiene el archivo apex original en forma desinflada con un nivel de compresión de 9 y con otros archivos almacenados sin comprimir.

Cuatro archivos comprenden un archivo APEX:

  • original_apex : desinflado con el nivel de compresión de 9 Este es el original, sin compresión de archivos APEX .
  • apex_manifest.pb : sólo se almacena
  • AndroidManifest.xml : sólo se almacena
  • apex_pubkey : sólo se almacena

El apex_manifest.pb , AndroidManifest.xml y apex_pubkey archivos son copias de sus archivos correspondientes en original_apex .

Construyendo APEX comprimido

APEX comprimido se puede construir utilizando la apex_compression_tool.py herramienta situada en el system/apex/tools .

Varios parámetros relacionados con la compresión APEX están disponibles en el sistema de compilación.

En Android.bp si un archivo APEX es compresible está controlado por el compressible propiedad:

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    compressible: true,
}

Un PRODUCT_COMPRESSED_APEX controles bandera producto ya sea una imagen del sistema integrado de la fuente deben contener archivos comprimidos APEX.

Para la experimentación local puede forzar a una acumulación vértices comprimir mediante el establecimiento de OVERRIDE_PRODUCT_COMPRESSED_APEX= a true .

Comprimido APEX archivos generados por el sistema de construcción tiene la .capex extensión. La extensión facilita la distinción entre las versiones comprimidas y sin comprimir de un archivo APEX.

Algoritmos de compresión compatibles

Android 12 solo admite la compresión desinflar-zip.

Activar un archivo APEX comprimido durante el arranque

Antes de que un APEX comprimido puede ser activado, el original_apex archivo dentro se descomprime en el /data/apex/decompressed directorio. El archivo descomprimido APEX resultante es duro vinculada a la /data/apex/active directorio.

Considere el siguiente ejemplo como una ilustración del proceso descrito anteriormente.

Considere /system/apex/com.android.foo.capex como APEX comprimido siendo activado, con versionCode 37.

  1. El original_apex archivo dentro /system/apex/com.android.foo.capex se descomprime en /data/apex/decompressed/com.android.foo@37.apex .
  2. restorecon /data/apex/decompressed/com.android.foo@37.apex se realiza para comprobar que tiene una etiqueta SELinux correcto.
  3. Verificación de los controles se realizan en /data/apex/decompressed/com.android.foo@37.apex para asegurar su validez: apexd comprueba la clave pública envuelta en /data/apex/decompressed/com.android.foo@37.apex a compruebe que sea igual a la incluida en /system/apex/com.android.foo.capex .
  4. El /data/apex/decompressed/com.android.foo@37.apex archivo es un enlace fijo a la /data/apex/active/com.android.foo@37.apex directorio.
  5. La lógica de activación normal para archivos sin comprimir APEX se realiza en /data/apex/active/com.android.foo@37.apex .

Interacción con OTA

Los archivos APEX comprimidos tienen implicaciones en la entrega y aplicación de OTA. Dado que una actualización OTA puede contener un archivo APEX comprimido con un nivel de versión superior al que está activo en un dispositivo, se debe reservar una cierta cantidad de espacio libre antes de reiniciar un dispositivo para aplicar una actualización OTA.

Para apoyar el sistema OTA, apexd expone a estos dos API aglutinantes:

  • calculateSizeForCompressedApex - calcula el tamaño necesario para descomprimir los archivos APEX en un paquete OTA. Esto se puede usar para verificar que un dispositivo tenga suficiente espacio antes de que se descargue una OTA.
  • reserveSpaceForCompressedApex - reserva espacio en el disco para uso futuro por apexd para descomprimir los archivos APEX comprimido en el paquete OTA.

En el caso de una actualización A / B OTA, apexd intentos de descompresión en el fondo como parte de la rutina de la OTA postinstall. Si falla la descompresión, apexd realiza la descompresión durante el arranque que se aplica la actualización OTA.

Alternativas consideradas al desarrollar APEX

A continuación se muestran algunas opciones que AOSP consideró al diseñar el formato de archivo APEX y por qué se incluyeron o excluyeron.

Sistemas regulares de gestión de paquetes

Distribuciones de Linux tienen sistemas de gestión de paquetes como dpkg y rpm , que son de gran alcance, maduro y robusto. Sin embargo, no se adoptaron para APEX porque no pueden proteger los paquetes después de la instalación. La verificación se realiza solo cuando se están instalando paquetes. Los atacantes pueden romper la integridad de los paquetes instalados sin ser notados. Esta es una regresión para Android donde todos los componentes del sistema se almacenaron en sistemas de archivos de solo lectura cuya integridad está protegida por dm-verity para cada E / S. Cualquier manipulación de los componentes del sistema debe estar prohibida o ser detectable para que el dispositivo pueda negarse a arrancar si se ve comprometido.

dm-crypt para la integridad

Los archivos en un recipiente APEX son de una función de particiones (por ejemplo, el /system partición) que están protegidos por dm-Verity, donde se prohíbe cualquier modificación de los archivos, incluso después de que las particiones están montados. Para proporcionar el mismo nivel de seguridad a los archivos, todos los archivos en un APEX se almacenan en una imagen del sistema de archivos que se empareja con un árbol hash y un descriptor vbmeta. Sin dm-Verity, un ápice en el /data de la partición es vulnerable a modificaciones no deseadas que se hacen después de que haya sido verificado e instalado.

De hecho, el /data partición también está protegida por capas de cifrado tales como dm-crypt. Aunque esto proporciona cierto nivel de protección contra la manipulación, su propósito principal es la privacidad, no la integridad. Cuando un atacante obtiene acceso a la /data de partición, no puede haber una mayor protección, y esto de nuevo es una regresión en comparación con cada componente del sistema de estar en el /system partición. El árbol hash dentro de un archivo APEX junto con dm-verity proporciona el mismo nivel de protección de contenido.

Redirigir rutas de / system a / apex

Archivos de los componentes del sistema empaquetados en un ápice son accesibles a través de nuevos caminos como /apex/<name>/lib/libfoo.so . Cuando los archivos eran parte del /system partición, eran accesibles a través de vías como /system/lib/libfoo.so . Un cliente de un archivo APEX (otros archivos APEX o la plataforma) debe utilizar las nuevas rutas. Es posible que deba actualizar el código existente como resultado del cambio de ruta.

Aunque una forma de evitar el cambio de ruta es superponer el contenido del archivo en un archivo de APEX en el /system partición, el equipo de Android no se decidió archivos de superposición en la /system partición, porque esto podría afectar al rendimiento como el número de archivos que se superpone ( posiblemente incluso apilados uno tras otro) aumentó.

Otra opción era secuestrar funciones de acceso a archivos como open , stat , y readlink , por lo que las rutas que comienzan con /system se redirige a sus rutas correspondientes bajo /apex . El equipo de Android descartó esta opción porque no es factible cambiar todas las funciones que aceptan rutas. Por ejemplo, algunas aplicaciones enlazan estáticamente a Bionic, que implementa las funciones. En tales casos, esas aplicaciones no se redireccionan.