1# APEX File Format 2 3Android Pony EXpress (APEX) is a container format introduced in Android Q 4that is used in the install flow for lower-level system 5modules. This format facilitates the updates of system components that don't fit 6into the standard Android application model. Some example components are native 7services and libraries, hardware abstraction layers 8([HALs](/https://source.android.com/devices/architecture/hal-types)), runtime 9([ART](/https://source.android.com/devices/tech/dalvik)), and class libraries. 10 11The term "APEX" can also refer to an APEX file. 12 13## Background 14 15Although Android supports updates of modules that fit within the standard app 16model (for example, services, activities) via package installer apps (such as 17the Google Play Store app), using a similar model for lower-level OS components 18has the following drawbacks: 19 20- APK-based modules can't be used early in the boot sequence. The package 21 manager is the central repository of information about apps and can only be 22 started from the activity manager, which becomes ready in a later stage of 23 the boot procedure. 24- The APK format (particularly the manifest) is designed for Android apps and 25 system modules aren't always a good fit. 26 27## Design 28 29This section describes the high-level design of the APEX file format and the 30APEX manager, which is a service that manages APEX files. 31 32### APEX format 33 34This is the format of an APEX file. 35 36 37 38**Figure 1.** APEX file format 39 40At the top level, an APEX file is a zip file in which files are stored 41uncompressed and located at 4 KB boundaries. 42 43The four files in an APEX file are: 44 45- `apex_manifest.json` 46- `AndroidManifest.xml` 47- `apex_payload.img` 48- `apex_pubkey` 49 50The `apex_manifest.json` file contains the package name and version, which 51identify an APEX file. 52 53The `AndroidManifest.xml` file allows the APEX file to use APK-related tools and 54infrastructure such as ADB, PackageManager, and package installer apps (such as 55Play Store). For example, the APEX file can use an existing tool such as `aapt` 56to inspect basic metadata from the file. The file contains package name and 57version information. This information is generally also available in 58`apex_manifest.json`. `AndroidManifest.xml` might contain additional 59targeting information that can be used by the existing app publishing tools. 60 61`apex_manifest.json` is recommended over `AndroidManifest.xml` for new code and 62systems that deal with APEX. 63 64`apex_payload.img` is an ext4 file system image backed by dm-verity. The image 65is mounted at runtime via a loop device. Specifically, the hash tree and 66metadata block are created using libavb. The file system payload isn't parsed 67(because the image should be mountable in place). Regular files are included 68inside the `apex_payload.img` file. 69 70`apex_pubkey` is the public key used to sign the file system image. At runtime, 71this key ensures that the downloaded APEX is signed with the same entity 72that signs the same APEX in the built-in partitions. 73 74### APEX manager 75 76The APEX manager (or `apexd`) is a native daemon responsible for 77verifying, installing, and uninstalling APEX files. This process is launched and 78is ready early in the boot sequence. APEX files are normally pre-installed on 79the device under `/system/apex`. The APEX manager defaults to using these 80packages if no updates are available. 81 82The update sequence of an APEX uses the 83[PackageManager class](https://developer.android.com/reference/android/content/pm/PackageManager) 84and is as follows. 85 861. An APEX file is downloaded via a package installer app, ADB, or other 87 source. 881. The package manager starts the installation procedure. Upon recognizing that 89 the file is an APEX, the package manager transfers control to the APEX 90 manager. 911. The APEX manager verifies the APEX file. 921. If the APEX file is verified, the internal database of the APEX manager is 93 updated to reflect that the APEX file will be activated at next boot. 941. The requestor of the install receives a broadcast upon successful 95 verification of the package. 961. To continue the installation, the system automatically reboots the device. 971. At reboot, the APEX manager starts, reads the internal database, and does 98 the following for each APEX file listed: 99 100 1. Verifies the APEX file. 101 1. Creates a loop device from the APEX file. 102 1. Creates a device mapper block device on top of the loop device. 103 1. Mounts the device mapper block device onto a unique path (for example, 104 <code>/apex/<var>name</var>@<var>ver</var></code>). 105 106When all APEX files listed in the internal database are mounted, the APEX 107manager provides a binder service for other system components to query 108information about the installed APEX files. For example, the other system 109components can query the list of APEX files installed in the device or query the 110exact path where a specific APEX is mounted, so the files can be accessed. 111 112### APEX files are APK files 113 114APEX files are valid APK files because they are signed zip archives (using the 115APK signature scheme) containing an `AndroidManifest.xml` file. This allows APEX 116files to use the infrastructure for APK files, such as a package installer app, 117the signing utility, and the package manager. 118 119The `AndroidManifest.xml` file inside an APEX file is minimal, consisting of the 120package `name`, `versionCode`, and optional `targetSdkVersion`, `minSdkVersion`, 121and `maxSdkVersion` for fine-grained targeting. This information allows APEX 122files to be delivered via existing channels such as package installer apps and 123ADB. 124 125### File types supported 126 127The APEX format supports these file types: 128 129- Native shared libs 130- Native executables 131- JAR files 132- Data files 133- Config files 134 135The APEX format can only update some of these file types. Whether a file 136type can be updated depends on the platform and how stable the interfaces for 137the files types are defined. 138 139### Signing 140 141APEX files are signed in two ways. First, the `apex_payload.img` (specifically, 142the vbmeta descriptor appended to `apex_payload.img`) file is signed with a key. 143Then, the entire APEX is signed using the 144[APK signature scheme v3](/https://source.android.com/security/apksigning/v3). Two different keys are used 145in this process. 146 147On the device side, a public key corresponding to the private key used to sign 148the vbmeta descriptor is installed. The APEX manager uses the public key to 149verify APEXs that are requested to be installed. Each APEX must be signed with 150different keys and is enforced both at build time and runtime. 151 152### APEX in built-in partitions 153 154APEX files can be located in built-in partitions such as `/system`. The 155partition is 156already over dm-verity, so the APEX files are mounted directly over the loop 157device. 158 159If an APEX is present in a built-in partition, the APEX can be updated by 160providing an APEX package with the same package name and a higher version code. 161The new APEX is stored in `/data` and, similar to APKs, the newer version 162shadows the version already present in the built-in partition. But unlike APKs, 163the newer version of the APEX is only activated after reboot. 164 165## Kernel requirements 166 167To support APEX mainline modules on an Android device, the following Linux 168kernel features are required: the loop driver and dm-verity. The loop 169driver mounts the file system image in an APEX module and dm-verity verifies the 170APEX module. 171 172The performance of the loop driver and dm-verity is important in achieving 173good system performance when using APEX modules. 174 175### Supported kernel versions 176 177APEX mainline modules are supported on devices using kernel versions 4.4 or 178higher. New devices launching with Android Q or higher 179must use kernel version 4.9 or higher to support APEX modules. 180 181### Required kernel patches 182 183The required kernel patches for supporting APEX modules are included in the 184Android common tree. To get the patches to support APEX, use the latest version 185of the Android common tree. 186 187#### Kernel version 4.4 188 189This version is only supported for devices that are upgraded from Android 9 to 190Android Q and want to support APEX modules. To get the 191required patches, a down-merge from the `android-4.4` branch is strongly 192recommended. The following is a list of the required individual patches 193for kernel version 4.4. 194 195- UPSTREAM: loop: add ioctl for changing logical block size 196 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777013){: .external}) 197- BACKPORT: block/loop: set hw_sectors 198 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777014/7){: .external}) 199- UPSTREAM: loop: Add LOOP_SET_BLOCK_SIZE in compat ioctl 200 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777015/7){: .external}) 201- ANDROID: mnt: Fix next_descendent 202 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/405314){: .external}) 203- ANDROID: mnt: remount should propagate to slaves of slaves 204 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/320406){: .external}) 205- ANDROID: mnt: Propagate remount correctly 206 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/928253){: .external}) 207- Revert "ANDROID: dm verity: add minimum prefetch size" 208 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/867875){: .external}) 209- UPSTREAM: loop: drop caches if offset or block_size are changed 210 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/854265){: .external}) 211 212#### Kernel versions 4.9/4.14/4.19 213 214To get the required patches for kernel versions 4.9/4.14/4.19, down-merge from 215the `android-common` branch. 216 217### Required kernel configuration options 218 219The following list shows the base configuration requirements for supporting 220APEX modules that were introduced in Android Q. The 221items with an asterisk (\*) are existing requirements from Android 9 and lower. 222 223``` 224(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices) 225CONFIG_BLK_DEV_LOOP=Y # for loop device support 226CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices 227(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity 228(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity 229CONFIG_DM_VERITY=Y # DM-verity support 230``` 231 232### Kernel command line parameter requirements 233 234To support APEX, make sure the kernel command line parameters meet the following 235requirements. 236 237- `loop.max_loop` must NOT be set 238- `loop.max_part` must be <= 8 239 240## Building an APEX 241 242Note: Because the implementation details for APEX are still under development, 243the content in this section is subject to change. 244 245This section describes how to build an APEX using the Android build system. 246The following is an example of `Android.bp` for an APEX named `apex.test`. 247 248``` 249apex { 250 name: "apex.test", 251 manifest: "apex_manifest.json", 252 file_contexts: "file_contexts", 253 // libc.so and libcutils.so are included in the apex 254 native_shared_libs: ["libc", "libcutils"], 255 binaries: ["vold"], 256 java_libs: ["core-all"], 257 prebuilts: ["my_prebuilt"], 258 compile_multilib: "both", 259 key: "apex.test.key", 260 certificate: "platform", 261} 262``` 263 264`apex_manifest.json` example: 265 266``` 267{ 268 "name": "com.android.example.apex", 269 "version": 1 270} 271``` 272 273`file_contexts` example: 274 275``` 276(/.*)? u:object_r:system_file:s0 277/sub(/.*)? u:object_r:sub_file:s0 278/sub/file3 u:object_r:file3_file:s0 279``` 280 281#### File types and locations in APEX 282 283|File type |Location in APEX | 284|-------------------|--------------------------------------------------------------| 285|Shared libraries |`/lib` and `/lib64` (`/lib/arm` for translated arm in x86) | 286|Executables |`/bin` | 287|Java libraries |`/javalib` | 288|Prebuilts |`/etc` | 289 290### Transitive dependencies 291 292APEX files automatically include transitive dependencies of native shared libs 293or executables. For example, if `libFoo` depends on `libBar`, the two libs are 294included when only `libFoo` is listed in the `native_shared_libs` property. 295 296### Handling multiple ABIs 297 298Install the `native_shared_libs` property for both primary and secondary 299application binary interfaces (ABIs) of the device. If an APEX targets devices 300with a single ABI (that is, 32 bit only or 64 bit only), only libraries with the 301corresponding ABI are installed. 302 303Install the `binaries` property only for the primary ABI of the device as 304described below: 305 306- If the device is 32 bit only, only the 32-bit variant of the binary is 307 installed. 308- If the device supports both 32/64 ABIs, but with 309 `TARGET_PREFER_32_BIT_EXECUTABLES=true`, then only the 32-bit variant of the 310 binary is installed. 311- If the device is 64 bit only, then only the 64-bit variant of the binary is 312 installed. 313- If the device supports both 32/64 ABIs, but without 314 TARGET_PREFER_32_BIT_EXECUTABLES`=true`, then only the 64-bit variant of the 315 binary is installed. 316 317To add fine-grained control over the ABIs of the native libraries and binaries, 318use the 319`multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]` 320properties. 321 322- `first`: Matches the primary ABI of the device. This is the default for 323 binaries. 324- `lib32`: Matches the 32-bit ABI of the device, if supported. 325- `lib64`: Matches the 64-bit ABI of the device, it supported. 326- `prefer32`: Matches the 32-bit ABI of the device, if supported. If the 327 32-bit ABI isn't supported, matches the 64-bit ABI. 328- `both`: Matches both ABIs. This is the default for 329 `native_shared_libraries`. 330 331The `java`, `libraries`, and `prebuilts` properties are ABI-agnostic. 332 333This example is for a device that supports 32/64 and doesn't prefer 32: 334 335``` 336apex { 337 // other properties are omitted 338 native_shared_libs: ["libFoo"], // installed for 32 and 64 339 binaries: ["exec1"], // installed for 64, but not for 32 340 multilib: { 341 first: { 342 native_shared_libs: ["libBar"], // installed for 64, but not for 32 343 binaries: ["exec2"], // same as binaries without multilib.first 344 }, 345 both: { 346 native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib 347 binaries: ["exec3"], // installed for 32 and 64 348 }, 349 prefer32: { 350 native_shared_libs: ["libX"], // installed for 32, but not for 64 351 }, 352 lib64: { 353 native_shared_libs: ["libY"], // installed for 64, but not for 32 354 }, 355 }, 356} 357``` 358 359### vbmeta signing 360 361Sign each APEX with different keys. When a new key is required, create a 362public-private key pair and make an `apex_key` module. Use the `key` property to 363sign the APEX using the key. The public key is automatically included in the 364APEX with the name `avb_pubkey`. 365 366Create an rsa key pair. 367 368``` 369$ openssl genrsa -out foo.pem 4096 370``` 371 372Extract the public key from the key pair. 373 374``` 375$ avbtool extract_public_key --key foo.pem --output foo.avbpubkey 376``` 377 378In Android.bp: 379``` 380apex_key { 381 name: "apex.test.key", 382 public_key: "foo.avbpubkey", 383 private_key: "foo.pem", 384} 385``` 386 387In the above example, the name of the public key (`foo`) becomes the ID of the 388key. The ID of the key used to sign an APEX is written in the APEX. At runtime, 389`apexd` verifies the APEX using a public key with the same ID in the device. 390 391### ZIP signing 392 393Sign APEXs in the same way as APKs. Sign APEXs twice, once for the mini file 394system (`apex_payload.img` file) and once for the entire file. 395 396To sign an APEX at the file-level, set the `certificate` property in one of 397these three ways: 398 399- Not set: If no value is set, the APEX is signed with the certificate located 400 at `PRODUCT_DEFAULT_DEV_CERTIFICATE`. If no flag is set, the path defaults 401 to `build/target/product/security/testkey`. 402- `<name>`: The APEX is signed with the `<name>` certificate in the same 403 directory as `PRODUCT_DEFAULT_DEV_CERTIFICATE`. 404- `:<name>`: The APEX is signed with the certificate that is defined by the 405 Soong module named `<name>`. The certificate module can be defined as 406 follows. 407 408``` 409android_app_certificate { 410 name: "my_key_name", 411 certificate: "dir/cert", 412 // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key) 413} 414``` 415 416Note: The `key` and `certificate` values do NOT need to be derived from the same 417public/private key pairs. APK signing (specified by `certificate`) is required 418because an APEX is an APK. 419 420## Installing an APEX 421 422To install an APEX, use ADB. 423 424``` 425$ adb install apex_file_name 426$ adb reboot 427``` 428 429## Using an APEX 430 431After reboot, the APEX is mounted at the `/apex/<apex_name>@<version>` 432directory. Multiple versions of the same APEX can be mounted at the same time. 433Among the mount paths, the one that corresponds to the latest version is 434bind-mounted at `/apex/<apex_name>`. 435 436Clients can use the bind-mounted path to read or execute files from APEX. 437 438APEXs are typically used as follows: 439 4401. An OEM or ODM preloads an APEX under `/system/apex` when the device is 441 shipped. 4421. Files in the APEX are accessed via the `/apex/<apex_name>/` path. 4431. When an updated version of the APEX is installed in `/data/apex`, the path 444 points to the new APEX after reboot. 445 446### Updating a service with an APEX 447 448To update a service using an APEX: 449 4501. Mark the service in the system partition as updatable. Add the option 451 `updatable` to the service definition. 452 453 ``` 454 /system/etc/init/myservice.rc: 455 456 service myservice /system/bin/myservice 457 class core 458 user system 459 ... 460 updatable 461 ``` 462 4631. Create a new `.rc` file for the updated service. Use the `override` option 464 to redefine the existing service. 465 466 ``` 467 /apex/my.apex@1/etc/init.rc: 468 469 service myservice /apex/my.apex@1/bin/myservice 470 class core 471 user system 472 ... 473 override 474 ``` 475 476Service definitions can only be defined in the `.rc` file of an APEX. Action 477triggers aren't supported in APEXs. 478 479If a service marked as updatable starts before the APEXs are activated, the 480start is delayed until the activation of the APEXs is complete. 481 482## Configuring system to support APEX updates 483 484Set the following system property to `true` to support APEX file updates. 485 486``` 487<device.mk>: 488 489PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true 490 491BoardConfig.mk: 492TARGET_FLATTEN_APEX := false 493``` 494 495or just 496 497``` 498<device.mk>: 499 500$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk) 501``` 502 503## Flattened APEX 504 505For legacy devices, it is sometimes impossible or infeasible to update the old 506kernel to fully support APEX. For example, the kernel might have been built 507without `CONFIG_BLK_DEV_LOOP=Y`, which is crucial for mounting the file system 508image inside an APEX. 509 510Flattened APEX is a specially built APEX that can be activated on devices with 511a legacy kernel. Files in a flattened APEX are directly installed to a directory 512under the built-in partition. For example, `lib/libFoo.so` in a flattend APEX 513`my.apex` is installed to `/system/apex/my.apex/lib/libFoo.so`. 514 515Activating a flattened APEX doesn't involve the loop device. The entire 516directory `/system/apex/my.apex` is directly bind-mounted to `/apex/name@ver`. 517 518Flattened APEXs can't be updated by downloading updated versions 519of the APEXs from network because the downloaded APEXs can't be flattened. 520Flattened APEXs can be updated only via a regular OTA. 521 522Note that flattened APEX is the default configuration for now. This means all 523APEXes are by default flattened unless you explicitly configure your device 524to support updatable APEX (explained above). 525 526Also note that, mixing flattened and non-flattened APEXes in a device is NOT 527supported. It should be either all non-flattened or all flattened. This is 528especially important when shipping pre-signed APEX prebuilts for the projects 529like Mainline. APEXes that are not pre-signed (i.e. built from the source) 530should also be non-flattened and signed with proper keys in that case. The 531device should inherit from `updatable_apex.mk` as explained above. 532 533## Alternatives considered when developing APEX 534 535Here are some options that we considered when designing the APEX file 536format, and why we included or excluded them. 537 538### Regular package management systems 539 540Linux distributions have package management systems like `dpkg` and `rpm`, 541which are powerful, mature and robust. However, they weren't 542adopted for APEX because they can't protect the packages after 543installation. Verification is done only when packages are being installed. 544Attackers can break the integrity of the installed packages unnoticed. This is 545a regression for Android where all system components were stored in read-only 546file systems whose integrity is protected by dm-verity for every I/O. Any 547tampering to system components must be prohibited, or be detectable so that 548the device can refuse to boot if compromised. 549 550### dm-crypt for integrity 551 552The files in an APEX container are from built-in partitions (for example, the 553`/system` partition) that are protected by dm-verity, where any modification to 554the files are prohibited even after the partitions are mounted. To provide the 555same level of security to the files, all files in an APEX are stored in a file 556system image that is paired with a hash tree and a vbmeta descriptor. Without 557dm-verity, an APEX in the `/data` partition is vulnerable to unintended 558modifications made after it's verified and installed. 559 560In fact, the `/data` partition is also protected by encryption layers such as 561dm-crypt. Although this provides some level of protection against tampering, its 562primary purpose is privacy, not integrity. When an attacker gains access to the 563`/data` partition, there can be no further protection, and this again is a 564regression compared to every system component being in the `/system` partition. 565The hash tree inside an APEX file together with dm-verity provides the same 566level of content protection. 567 568### Redirecting paths from `/system` to `/apex` 569 570System component files packaged in an APEX are accessible via new paths like 571`/apex/<name>/lib/libfoo.so`. When the files were part of the `/system` 572partition, they were accessible via paths such as `/system/lib/libfoo.so`. A 573client of an APEX file (other APEX files or the platform) should use the new 574paths. This change in paths might require updates to the existing code. 575 576One way to avoid the path change is to overlay the file contents in an APEX 577file over the `/system` partition. However, we decided not to overlay files over 578the `/system` partition because we believed this would negatively affect 579performance as the number of files being overlayed (possibly even stacked one 580after another) increases. 581 582Another option was to hijack file access functions such as `open`, `stat`, and 583`readlink`, so that paths that start with `/system` are redirected to their 584corresponding paths under `/apex`. We discarded this option because it's 585practically infeasible to change all functions that accept paths. For 586example, some apps statically link Bionic, which implements the functions. In 587that case, the redirection won't happen for the app. 588