El formato de contenedor Android Pony EXpress (APEX) se introdujo en Android. (10) y se usa en el flujo de instalación para sistemas de nivel módulos. Este formato facilita las actualizaciones de los componentes del sistema que no se ajustan en el modelo de aplicación estándar de Android. Algunos ejemplos de componentes son nativos servicios 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 hacer referencia a un archivo APEX.
Segundo plano
Si bien Android admite actualizaciones de módulos que se ajustan a la app estándar (por ejemplo, servicios, actividades) a través de apps de instalación de paquetes (como la app de Google Play Store) con un modelo similar para los componentes de SO de nivel inferior tiene las siguientes desventajas:
- Los módulos basados en APK no se pueden usar al principio de la secuencia de inicio. El paquete es el repositorio central de información sobre apps y solo se puede se inician desde el administrador de actividades, que se prepara en una etapa posterior del el procedimiento de inicio.
- El formato APK (especialmente el manifiesto) está diseñado para apps de Android y módulos de sistema no siempre son una buena opción.
Diseño
Esta sección describe el diseño general del formato de archivo APEX y las Administrador de APEX, un servicio que administra archivos APEX.
Para obtener más información sobre por qué se seleccionó este diseño para APEX, consulta Alternativas que se tienen en cuenta para desarrollar APEX
Formato APEX
Es el formato de un archivo APEX.
Figura 1: Formato de archivo APEX
En el nivel superior, un archivo APEX es un archivo ZIP en el que se almacenan los archivos está sin comprimir y tiene un límite de 4 KB.
Los cuatro archivos incluidos en un archivo APEX son los siguientes:
apex_manifest.json
AndroidManifest.xml
apex_payload.img
apex_pubkey
El archivo apex_manifest.json
contiene el nombre y la versión del paquete, que
identificar un archivo APEX. Este es un
ApexManifest
búfer de protocolo en formato JSON.
El archivo AndroidManifest.xml
permite que el archivo APEX use herramientas relacionadas con el APK.
como ADB, PackageManager y apps de instalación de paquetes (como
Play Store). Por ejemplo, el archivo APEX puede usar una herramienta existente, como aapt
para inspeccionar los metadatos básicos del archivo. El archivo contiene el nombre del paquete y
información de la versión. Por lo general, esta información también está disponible en
apex_manifest.json
Se recomienda usar apex_manifest.json
en lugar de AndroidManifest.xml
para el código nuevo y
los sistemas que trabajan con APEX. AndroidManifest.xml
podría incluir elementos
información de segmentación que pueden usar las herramientas existentes de publicación de apps.
apex_payload.img
es una imagen del sistema de archivos ext4 respaldada por dm-verity. La imagen
se monta en el tiempo de ejecución mediante un dispositivo de bucle invertido. Específicamente, el árbol de hash y
del bloque de metadatos se crean con la biblioteca libavb
. La carga útil del sistema de archivos
no se analiza (porque la imagen se debería poder montar). Los archivos regulares se
incluido dentro del archivo apex_payload.img
.
apex_pubkey
es la clave pública que se usa para firmar la imagen del sistema de archivos. Durante el tiempo de ejecución,
esta clave garantiza que el APEX descargado se firme con la misma entidad
que firme el mismo APEX en las particiones integradas.
Lineamientos para asignar nombres a APEX
Para evitar conflictos de nombres entre nuevos APEX a medida que avanza la plataforma, usa los siguientes lineamientos para asignar nombres:
com.android.*
- Reservado para APEX de AOSP. No es exclusivo de ninguna empresa o dispositivo.
com.<companyname>.*
- Está reservado para una empresa. Es posible que varios dispositivos puedan usarla. de la empresa.
com.<companyname>.<devicename>.*
- Reservado para APEX exclusivos de un dispositivo específico (o un subconjunto de dispositivos).
Administrador de APEX
El administrador de APEX (o apexd
) es un proceso nativo independiente que se encarga de
verificar, instalar y desinstalar archivos APEX Este proceso se inicia y
esté listo con anticipación en la secuencia de inicio. Los archivos APEX normalmente están preinstalados
el dispositivo en /system/apex
. El administrador de APEX usa de forma predeterminada estas
paquetes si no hay actualizaciones disponibles.
La secuencia de actualización de un APEX usa el Clase PackageManager y es la siguiente.
- Un archivo APEX se descarga mediante una app de instalación de paquetes, ADB u otro fuente.
- 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 archivo administrador.
- El administrador de APEX verifica el archivo correspondiente.
- Si se verifica el archivo APEX, la base de datos interna del administrador de APEX para reflejar que el archivo APEX se activa en el siguiente inicio.
- El solicitante de la instalación recibe una transmisión tras completar correctamente el paquete. verificación.
- Para continuar con la instalación, debes reiniciar el sistema.
En el siguiente inicio, el administrador de APEX se inicia, lee la base de datos interna lo siguiente para cada archivo APEX de la lista:
- Verifica el archivo APEX.
- Crea un dispositivo de bucle invertido a partir del archivo APEX.
- Crea un dispositivo de bloques de asignador de dispositivos sobre el dispositivo de bucle invertido.
- Activa el dispositivo de bloques del asignador de dispositivos en una ruta única (por ejemplo,
/apex/name@ver
).
Cuando se activan todos los archivos APEX de la base de datos interna, el archivo Manager proporciona un servicio de enlace para que otros componentes del sistema consulten información sobre los archivos APEX instalados. Por ejemplo, el otro sistema pueden consultar la lista de archivos APEX instalados en el dispositivo o consultar la ruta de acceso exacta donde se activa un APEX específico para que se pueda acceder a los archivos.
Los archivos APEX son archivos APK.
Los archivos APEX son archivos APK válidos porque son archivos ZIP firmados (con el
esquema de firma de APK) que contenga un archivo AndroidManifest.xml
. Esto permite que APEX
para usar la infraestructura de los archivos APK, como una aplicación de instalación de paquetes,
la utilidad de firma y el administrador de paquetes.
El archivo AndroidManifest.xml
dentro de un archivo APEX es mínimo y consta de lo siguiente:
los paquetes name
, versionCode
y targetSdkVersion
, minSdkVersion
,
y maxSdkVersion
para una segmentación detallada. Esta información permite que APEX
archivos que se entregarán a través de canales existentes, como aplicaciones de instalación de paquetes y
ADB.
Tipos de archivos compatibles
El formato APEX admite los siguientes tipos de archivos:
- Bibliotecas compartidas nativas
- Ejecutables nativos
- Archivos JAR
- Archivos de datos
- Archivos de configuración
Eso no significa que APEX pueda actualizar todos esos tipos de archivos. Si un archivo según la plataforma y la estabilidad de las definiciones de las interfaces de los tipos de archivos.
Opciones de firma
Los archivos APEX se firman de dos maneras. Primero, el elemento apex_payload.img
(específicamente,
el descriptor vbmeta agregado a apex_payload.img
) se firma con una clave.
Luego, se firma todo el APEX con el
Esquema de firma de APK v3 Se usan dos claves diferentes
en este proceso.
En el dispositivo, una clave pública correspondiente a la clave privada que se usa para firmar se instala el descriptor vbmeta. El administrador de APEX usa la clave pública para verificar los APEX que se solicita instalar. Cada APEX debe firmarse con diferentes claves y se aplica en el tiempo de compilación y en el entorno de ejecución.
APEX en particiones integradas
Los archivos APEX se pueden ubicar en particiones integradas, como /system
. El
la partición ya supera dm-verity, por lo que los archivos APEX se activan directamente
en el dispositivo de bucle invertido.
Si un APEX está presente en una partición integrada, el APEX se puede actualizar
proporcionar un paquete de APEX con el mismo nombre de paquete y un valor mayor o igual que
al código de versión. El nuevo APEX se almacena en /data
y, al igual que los APK, el
versión recién instalada sustituye a la que ya está presente en la
por cada partición. Pero, a diferencia de los APK,
la versión recién instalada de APEX
se activará después de reiniciar.
Requisitos del kernel
Para admitir módulos de línea principal de APEX en un dispositivo Android, las siguientes aplicaciones de Linux se requieren funciones de kernel: el controlador de bucle invertido y dm-verity. El bucle invertido activa la imagen del sistema de archivos en un módulo APEX y dm-verity verifica módulo APEX.
El rendimiento del controlador de bucle invertido y la dm-verity es importante para lograr un buen rendimiento del sistema cuando se usan módulos APEX.
Versiones de kernel compatibles
Los módulos de línea principal de APEX son compatibles con dispositivos que usan las versiones de kernel 4.4 o mayores. Dispositivos nuevos que se lanzan con Android 10 o versiones posteriores debes usar la versión de kernel 4.9 o superior para admitir módulos APEX.
Parches de kernel obligatorios
Los parches de kernel necesarios para admitir módulos de APEX se incluyen en la Árbol común de Android Para obtener los parches compatibles con APEX, usa la versión más reciente. del árbol común de Android.
Versión de kernel 4.4
Esta versión solo es compatible con dispositivos actualizados de Android 9 a
Android 10 y la intención de admitir módulos APEX Para obtener la
los parches necesarios, una división descendente de la rama android-4.4
se considera
se recomienda. La siguiente es una lista de los parches individuales necesarios
para la versión de kernel 4.4.
- UPSTREAM: bucle: agrega ioctl para cambiar el tamaño de bloque lógico (4.4).
- BACKPORT: block/loop: set hw_sectors (4.4).
- UPSTREAM: bucle: Agrega LOOP_SET_BLOCK_SIZE en ioctl compatible (4.4).
- ANDROID: mnt: Corrige next_descendent (4.4).
- ANDROID: mnt: volver a montar debe propagarse a los esclavos de esclavos (4.4).
- ANDROID: mnt: Propagar volver a activar correctamente (4.4).
- Revertir "ANDROID: dm verity: agregar tamaño mínimo de carga previa" (4.4).
- UPSTREAM: Bucle: descarta las cachés si se cambia offset o block_size (4.4).
Versiones de kernel 4.9/4.14/4.19
Para obtener los parches necesarios para las versiones de kernel 4.9/4.14/4.19, debes separarlos desde
la rama android-common
.
Opciones de configuración de kernel obligatorias
En la siguiente lista, se muestran los requisitos de configuración básica para admitir Módulos de APEX que se introdujeron en Android 10. Los elementos que tienen un asterisco (*) existen 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úrate de que los parámetros de la línea de comandos del kernel cumplan con los siguientes requisitos: requisitos:
- NO se debe establecer
loop.max_loop
loop.max_part
debe ser mayor que 8
Compila un APEX
En esta sección, se describe cómo compilar un APEX con el sistema de compilación de Android.
El siguiente es un ejemplo de Android.bp
para un APEX llamado 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",
}
Ejemplo de apex_manifest.json
:
{
"name": "com.android.example.apex",
"version": 1
}
Ejemplo de file_contexts
:
(/.*)? 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
brazo traducido a x86) |
Ejecutables | /bin |
Bibliotecas Java | /javalib |
Compilaciones previas | /etc |
Dependencias transitivas
Los archivos APEX incluyen automáticamente dependencias transitivas de bibliotecas nativas compartidas.
o ejecutables. Por ejemplo, si libFoo
depende de libBar
, las dos bibliotecas se
Se incluye cuando solo libFoo
aparece en la propiedad native_shared_libs
.
Cómo controlar varias ABI
Instala la propiedad native_shared_libs
para la instancia principal y la secundaria
interfaces binarias de la aplicación (ABI) del dispositivo. Si un APEX se orienta a dispositivos
con una única ABI (es decir, solo 32 bits o solo 64 bits), solo bibliotecas con el
ABI correspondiente.
Instala la propiedad binaries
solo para la ABI principal del dispositivo, como se muestra a continuación:
como se describe a continuación:
- Si el dispositivo es solo de 32 bits, únicamente se aplica la variante de 32 bits del objeto binario. esté instalado.
- Si el dispositivo es solo de 64 bits, entonces solo se aplica la variante de 64 bits del objeto binario. esté instalado.
Para agregar un control detallado sobre las ABI de las bibliotecas y los objetos binarios nativos,
usa el
multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]
propiedades.
first
: Coincide con la ABI principal del dispositivo. Esta es la configuración predeterminada binarios.lib32
: Coincide con la ABI de 32 bits del dispositivo, si es compatible.lib64
: Coincide con la ABI de 64 bits del dispositivo, que es compatible.prefer32
: Coincide con la ABI de 32 bits del dispositivo, si es compatible. Si el botón La ABI de 32 bits no es compatible; coincide con la de 64 bits.both
: Coincide con ambas ABI. Esta es la configuración predeterminadanative_shared_libraries
Las propiedades java
, libraries
y prebuilts
son independientes de la ABI.
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 requiera una clave nueva, crea un
clave pública-privada y crea un módulo apex_key
. Usa la propiedad key
para
Firma el APEX con la clave. La clave pública se incluye automáticamente en el
APEX con el nombre avb_pubkey
# create an rsa key pairopenssl genrsa -out foo.pem 4096
# extract the public key from the key pairavbtool extract_public_key --key foo.pem --output foo.avbpubkey
# in Android.bpapex_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
. El ID de la clave que se usa para firmar un APEX se escribe en ese archivo. Durante el tiempo de ejecución,
apexd
verifica APEX con una clave pública con el mismo ID en el dispositivo.
Firma de APEX
Firma los archivos de APEX de la misma manera en la que firmas los APK. Firma APEX dos veces. una vez para
minisistema de archivos (archivo apex_payload.img
) y una vez para todo el archivo.
Para firmar un APEX a nivel de archivo, establece la propiedad certificate
en uno de
estas tres maneras:
- No establecido: Si no se establece ningún valor, se firma el APEX con el certificado ubicado
a las
PRODUCT_DEFAULT_DEV_CERTIFICATE
. Si no se establece ninguna marca, los valores predeterminados de la ruta de acceso abuild/target/product/security/testkey
. <name>
: APEX está firmado con el certificado<name>
en el mismo comoPRODUCT_DEFAULT_DEV_CERTIFICATE
.:<name>
: El APEX está firmado con el certificado definido por el Módulo de Soong con el nombre<name>
. El módulo de certificado se puede definir como sigue.
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)
}
Instala un APEX
Para instalar un APEX, usa ADB.
adb install apex_file_name
adb reboot
Si supportsRebootlessUpdate
se establece como true
en apex_manifest.json
y
APEX instalado actualmente no se usa (por ejemplo, cualquier servicio que contenga tenga
se detuvo), se puede instalar un nuevo APEX sin reiniciarse con el
--force-non-staged
.
adb install --force-non-staged apex_file_name
Usa un archivo APEX
Después del reinicio, APEX se activa en la /apex/<apex_name>@<version>
.
. Se pueden activar varias versiones del mismo APEX al mismo tiempo.
Entre las rutas de activación, la que corresponde a la última versión es
se activa mediante vinculación en /apex/<apex_name>
.
Los clientes pueden usar la ruta de acceso activada por la vinculación para leer o ejecutar archivos desde APEX.
Por lo general, los APEX se usan de la siguiente manera:
- Un OEM o un ODM precarga un APEX en
/system/apex
cuando el dispositivo está enviado. - Se puede acceder a los archivos de APEX a través de la ruta de acceso
/apex/<apex_name>/
. - Cuando se instala una versión actualizada de APEX en
/data/apex
, la ruta de acceso apunta al nuevo APEX después del reinicio.
Actualiza un servicio con un APEX
Para actualizar un servicio con APEX, haz lo siguiente:
Marca el servicio en la partición del sistema como actualizable. Agrega 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
Crea un archivo
.rc
nuevo para el servicio actualizado. Usa la opciónoverride
para redefinir el servicio existente./apex/my.apex/etc/init.rc: service myservice /apex/my.apex/bin/myservice class core user system ... override
Las definiciones del servicio solo se pueden definir en el archivo .rc
de un APEX. Acción
no son compatibles con APEX.
Si un servicio marcado como actualizable se inicia antes de que se activen los APEX, el el inicio se retrasa hasta que se completa la activación de los APEX.
Cómo configurar el sistema para que admita actualizaciones de APEX
Configura la siguiente propiedad del sistema como true
para admitir actualizaciones de archivos 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 plano
En el caso de los dispositivos heredados, a veces es imposible o inviable actualizar la versión anterior
kernel para admitir APEX por completo. Por ejemplo, el kernel podría haberse compilado
sin CONFIG_BLK_DEV_LOOP=Y
, que es fundamental para activar el sistema de archivos
dentro de un archivo APEX.
Flattened APEX es un APEX diseñado especialmente 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 integrada. Por ejemplo, lib/libFoo.so
en un APEX plano
my.apex
está instalado en /system/apex/my.apex/lib/libFoo.so
.
La activación de un APEX plano no implica el uso del dispositivo de bucle. Todo el
El directorio /system/apex/my.apex
está activado de forma directa mediante /apex/name@ver
.
Los APEX planos no se pueden actualizar mediante la descarga de versiones actualizadas de los APEX de la red porque no se pueden compactar los descargados. Los APEX sin compactar se pueden actualizar solo a través de una OTA normal.
El APEX plano es la configuración predeterminada. Esto significa que todas Los APEX se aplanan de forma predeterminada, a menos que configures explícitamente tu dispositivo para crear APEX no planos para admitir actualizaciones de APEX (como se explicó anteriormente).
NO se permite mezclar APEX planos y no aplanados en un dispositivo
no es compatible. Los APEX de un dispositivo deben estar todos aplanados o no aplanados.
Esto es especialmente importante cuando se envían compilaciones previas de APEX firmadas previamente para
proyectos como Mainline. APEX que no están prefirmados (es decir, compilados a partir de
la fuente) también deben estar no compactados y firmados con las claves correctas. El
que el dispositivo debe heredar de updatable_apex.mk
, como se explica en
Actualiza un servicio con un APEX
APEX comprimidos
Android 12 y las versiones posteriores incluyen compresión de APEX para lo que reduce el impacto del almacenamiento de los paquetes de APEX actualizables. Después de la actualización de un APEX está instalado, aunque ya no se usa su versión preinstalada, sigue ocupando la misma cantidad de espacio. Ese espacio ocupado no estará disponible.
La compresión de APEX minimiza el impacto del almacenamiento mediante un conjunto muy comprimido
de archivos APEX en particiones de solo lectura (como la partición /system
). En Android
12 y, luego, utilizan un algoritmo de compresión de zip DEFLATE.
La compresión no optimiza los siguientes elementos:
APEX de arranque que se deben activar muy pronto en el arranque secuencia.
APEX no actualizables. La compresión solo es beneficiosa si hay instalada una versión actualizada de APEX en la partición
/data
. Encontrarás una lista completa de APEX actualizables en la Componentes modulares del sistema .APEX de bibliotecas compartidas dinámicas. Dado que
apexd
siempre activa ambas versiones de como APEX (preinstalados y actualizados), comprimirlos no agrega valor.
Formato de archivo APEX comprimido
Este es el formato de un archivo APEX comprimido.
Figura 2: Formato de archivo APEX comprimido
En el nivel superior, un archivo APEX comprimido es un archivo ZIP que contiene el archivo archivo principal en formato desinflado con un nivel de compresión de 9 y con otros archivos se almacenan sin comprimir.
Hay cuatro archivos que componen un archivo APEX:
original_apex
: se desinfla con un nivel de compresión de 9 Este es el archivo APEX original sin comprimir.apex_manifest.pb
: solo almacenadosAndroidManifest.xml
: solo almacenadosapex_pubkey
: solo almacenados
Los archivos apex_manifest.pb
, AndroidManifest.xml
y apex_pubkey
tienen las siguientes características:
copias de los archivos correspondientes en original_apex
.
Cómo compilar APEX comprimido
El APEX comprimido se puede compilar con la herramienta apex_compression_tool.py
ubicada en
system/apex/tools
Varios parámetros relacionados con la compresión de APEX están disponibles en el sistema de compilación.
En Android.bp
, si un archivo APEX es comprimible estará controlado por el
Propiedad compressible
:
apex {
name: "apex.test",
manifest: "apex_manifest.json",
file_contexts: "file_contexts",
compressible: true,
}
Una marca de producto PRODUCT_COMPRESSED_APEX
controla si se compiló una imagen del sistema
de la fuente debe contener archivos APEX comprimidos.
Para realizar experimentos locales, puedes forzar una compilación para comprimir APEX configurando
De OVERRIDE_PRODUCT_COMPRESSED_APEX=
a true
.
Los archivos APEX comprimidos que genera el sistema de compilación tienen la extensión .capex
.
La extensión facilita la distinción entre comprimido y sin comprimir
de un archivo APEX.
Algoritmos de compresión compatibles
Android 12 solo admite la compresión de deflate-zip.
Cómo activar un archivo APEX comprimido durante el inicio
Antes de que se pueda activar un APEX comprimido, el archivo original_apex
descomprimido en el directorio /data/apex/decompressed
. El resultado
El archivo APEX descomprimido está vinculado al directorio /data/apex/active
.
Considera el siguiente ejemplo como ejemplo del proceso descrito anteriormente.
Considera /system/apex/com.android.foo.capex
como un APEX comprimido que es
activada con el código de versión 37.
- El archivo
original_apex
dentro de/system/apex/com.android.foo.capex
es se descomprime en/data/apex/decompressed/com.android.foo@37.apex
. - Se realiza
restorecon /data/apex/decompressed/com.android.foo@37.apex
para verificar que tenga una etiqueta de SELinux correcta. - Las verificaciones se realizan en
/data/apex/decompressed/com.android.foo@37.apex
para garantizar su validez:apexd
verifica la clave pública agrupada en/data/apex/decompressed/com.android.foo@37.apex
para verificar que sea igual al que se incluye en/system/apex/com.android.foo.capex
. - El archivo
/data/apex/decompressed/com.android.foo@37.apex
está vinculado de forma fija a el directorio/data/apex/active/com.android.foo@37.apex
. - La lógica de activación normal para archivos APEX sin comprimir 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 la aplicación de OTA. Desde una actualización inalámbrica puede incluir un archivo APEX comprimido con un nivel de versión superior que la actividad de un dispositivo, se debe reservar cierta cantidad de espacio libre antes de que se reinicie un dispositivo para aplicar una actualización OTA.
Para admitir el sistema inalámbrico, apexd
expone estas dos APIs de Binder:
calculateSizeForCompressedApex
: calcula el tamaño necesario para descomprimir. APEX en un paquete inalámbrico. Se puede usar para verificar que un dispositivo tenga espacio suficiente antes de que se descargue una actualización inalámbrica.reserveSpaceForCompressedApex
: Reserva espacio en el disco para uso futuro. porapexd
para descomprimir archivos APEX comprimidos dentro del paquete inalámbrico.
En el caso de una actualización inalámbrica A/B, apexd
intenta la descompresión en la
en segundo plano como parte de la rutina OTA posterior a la instalación. Si la descompresión falla,
apexd
realiza la descompresión durante el inicio que aplica la OTA.
actualización.
Alternativas que se tienen en cuenta para desarrollar APEX
Estas son algunas opciones que AOSP tuvo en cuenta cuando diseñó el archivo APEX y por qué se incluyeron o excluyeron.
Sistemas de administración de paquetes regulares
Las distribuciones de Linux tienen sistemas de administración de paquetes, como dpkg
y rpm
,
potentes, maduras y robustas. Sin embargo, no fueron
para APEX porque no pueden proteger los paquetes después
instalación. La verificación se realiza solo cuando se instalan los paquetes.
Los atacantes pueden romper la integridad de los paquetes instalados, desapercibidos. Este es
una regresión para Android en la que todos los componentes del sistema se almacenaban en modo
de archivos cuya integridad está protegida por dm-verity para cada E/S. Cualquiera
manipular componentes del sistema debe estar prohibido o ser detectable, por lo que
que el dispositivo puede negarse a iniciarse si se vulnera.
dm-crypt para la integridad
Los archivos de un contenedor de APEX provienen de particiones integradas (por ejemplo, el
/system
) que están protegidas por dm-verity, donde cualquier modificación a
los archivos están prohibidos incluso después de que se activan las particiones. Para proporcionar
mismo nivel de seguridad a los archivos, todos los archivos en un APEX se almacenan en un archivo
que se vincula con un árbol de hash y un descriptor vbmeta. Sin
dm-verity, un APEX en la partición /data
es vulnerable a problemas
las modificaciones que se hacen
después de su verificación e instalación.
De hecho, la partición /data
también está protegida por capas de encriptación, como las siguientes:
dm-crypt. Aunque esto brinda cierto nivel de protección contra la manipulación, su
cuyo propósito principal es la privacidad, no la integridad. Cuando un atacante consigue acceso al
/data
, no puede haber más protección,
de regresión en comparación con cada componente del sistema que se encuentra en la partición /system
.
El árbol de hash dentro de un archivo APEX junto con dm-verity proporciona la misma
el nivel de protección del contenido.
Redireccionar rutas de /system a /apex
Se puede acceder a los archivos de componentes del sistema empaquetados en un APEX a través de rutas nuevas, como
/apex/<name>/lib/libfoo.so
Cuando los archivos formaban parte de /system
de la partición, se podía acceder a ellas mediante rutas como /system/lib/libfoo.so
. R
de un archivo APEX (otros archivos APEX o la plataforma) debe utilizar el nuevo archivo
rutas de ataque. Es posible que debas actualizar el código existente como resultado del cambio de la ruta de acceso.
Aunque una forma de evitar este cambio es superponer el contenido del archivo en una
archivo APEX en la partición /system
, el equipo de Android decidió no superponer
archivos en la partición /system
, ya que esto podría afectar el rendimiento, ya que
cantidad de archivos que se superponen (posiblemente incluso se apilan uno tras otro)
aumentó.
Otra opción era apropiarse de funciones de acceso a archivos como open
, stat
y
readlink
para que las rutas de acceso que comienzan con /system
se redirigen a su
las rutas correspondientes en /apex
. El equipo de Android descartó esta opción.
porque es inviable cambiar todas las funciones que aceptan rutas.
Por ejemplo, algunas apps vinculan de forma estática Bionic, que implementa las funciones.
En esos casos, esas apps no se redireccionan.