1*33f37583SAndroid Build Coastguard Worker# APEX File Format 2*33f37583SAndroid Build Coastguard Worker 3*33f37583SAndroid Build Coastguard WorkerAndroid Pony EXpress (APEX) is a container format introduced in Android Q that 4*33f37583SAndroid Build Coastguard Workeris used in the install flow for lower-level system modules. This format 5*33f37583SAndroid Build Coastguard Workerfacilitates the updates of system components that don't fit into the standard 6*33f37583SAndroid Build Coastguard WorkerAndroid application model. Some example components are native services and 7*33f37583SAndroid Build Coastguard Workerlibraries, hardware abstraction layers 8*33f37583SAndroid Build Coastguard Worker([HALs](/https://source.android.com/devices/architecture/hal-types)), runtime 9*33f37583SAndroid Build Coastguard Worker([ART](/https://source.android.com/devices/tech/dalvik)), and class libraries. 10*33f37583SAndroid Build Coastguard Worker 11*33f37583SAndroid Build Coastguard WorkerThe term "APEX" can also refer to an APEX file. 12*33f37583SAndroid Build Coastguard Worker 13*33f37583SAndroid Build Coastguard WorkerThis document describes technical details of the APEX file format. If you are 14*33f37583SAndroid Build Coastguard Workerlooking at how to build an APEX package, kindly refer to [this how-to](howto.md) 15*33f37583SAndroid Build Coastguard Workerdocument. 16*33f37583SAndroid Build Coastguard Worker 17*33f37583SAndroid Build Coastguard Worker## Background 18*33f37583SAndroid Build Coastguard Worker 19*33f37583SAndroid Build Coastguard WorkerAlthough Android supports updates of modules that fit within the standard app 20*33f37583SAndroid Build Coastguard Workermodel (for example, services, activities) via package installer apps (such as 21*33f37583SAndroid Build Coastguard Workerthe Google Play Store app), using a similar model for lower-level OS components 22*33f37583SAndroid Build Coastguard Workerhas the following drawbacks: 23*33f37583SAndroid Build Coastguard Worker 24*33f37583SAndroid Build Coastguard Worker- APK-based modules can't be used early in the boot sequence. The package 25*33f37583SAndroid Build Coastguard Worker manager is the central repository of information about apps and can only be 26*33f37583SAndroid Build Coastguard Worker started from the activity manager, which becomes ready in a later stage of 27*33f37583SAndroid Build Coastguard Worker the boot procedure. 28*33f37583SAndroid Build Coastguard Worker- The APK format (particularly the manifest) is designed for Android apps and 29*33f37583SAndroid Build Coastguard Worker system modules aren't always a good fit. 30*33f37583SAndroid Build Coastguard Worker 31*33f37583SAndroid Build Coastguard Worker## Design 32*33f37583SAndroid Build Coastguard Worker 33*33f37583SAndroid Build Coastguard WorkerThis section describes the high-level design of the APEX file format and the 34*33f37583SAndroid Build Coastguard WorkerAPEX manager, which is a service that manages APEX files. 35*33f37583SAndroid Build Coastguard Worker 36*33f37583SAndroid Build Coastguard Worker### APEX format {#apex-format} 37*33f37583SAndroid Build Coastguard Worker 38*33f37583SAndroid Build Coastguard WorkerThis is the format of an APEX file. 39*33f37583SAndroid Build Coastguard Worker 40*33f37583SAndroid Build Coastguard Worker 41*33f37583SAndroid Build Coastguard Worker 42*33f37583SAndroid Build Coastguard Worker**Figure 1.** APEX file format 43*33f37583SAndroid Build Coastguard Worker 44*33f37583SAndroid Build Coastguard WorkerAt the top level, an APEX file is a zip file in which files are stored 45*33f37583SAndroid Build Coastguard Workeruncompressed and located at 4 KB boundaries. 46*33f37583SAndroid Build Coastguard Worker 47*33f37583SAndroid Build Coastguard WorkerThe four files in an APEX file are: 48*33f37583SAndroid Build Coastguard Worker 49*33f37583SAndroid Build Coastguard Worker- `apex_manifest.json` 50*33f37583SAndroid Build Coastguard Worker- `AndroidManifest.xml` 51*33f37583SAndroid Build Coastguard Worker- `apex_payload.img` 52*33f37583SAndroid Build Coastguard Worker- `apex_pubkey` 53*33f37583SAndroid Build Coastguard Worker 54*33f37583SAndroid Build Coastguard WorkerThe `apex_manifest.json` file contains the package name and version, which 55*33f37583SAndroid Build Coastguard Workeridentify an APEX file. 56*33f37583SAndroid Build Coastguard Worker 57*33f37583SAndroid Build Coastguard WorkerThe `AndroidManifest.xml` file allows the APEX file to use APK-related tools and 58*33f37583SAndroid Build Coastguard Workerinfrastructure such as ADB, PackageManager, and package installer apps (such as 59*33f37583SAndroid Build Coastguard WorkerPlay Store). For example, the APEX file can use an existing tool such as `aapt` 60*33f37583SAndroid Build Coastguard Workerto inspect basic metadata from the file. The file contains package name and 61*33f37583SAndroid Build Coastguard Workerversion information. This information is generally also available in 62*33f37583SAndroid Build Coastguard Worker`apex_manifest.json`. `AndroidManifest.xml` might contain additional targeting 63*33f37583SAndroid Build Coastguard Workerinformation that can be used by the existing app publishing tools. 64*33f37583SAndroid Build Coastguard Worker 65*33f37583SAndroid Build Coastguard Worker`apex_manifest.json` is recommended over `AndroidManifest.xml` for new code and 66*33f37583SAndroid Build Coastguard Workersystems that deal with APEX. 67*33f37583SAndroid Build Coastguard Worker 68*33f37583SAndroid Build Coastguard Worker`apex_payload.img` is an ext4 file system image backed by dm-verity. The image 69*33f37583SAndroid Build Coastguard Workeris mounted at runtime via a loop device. Specifically, the hash tree and 70*33f37583SAndroid Build Coastguard Workermetadata block are created using libavb. The file system payload isn't parsed 71*33f37583SAndroid Build Coastguard Worker(because the image should be mountable in place). Regular files are included 72*33f37583SAndroid Build Coastguard Workerinside the `apex_payload.img` file. 73*33f37583SAndroid Build Coastguard Worker 74*33f37583SAndroid Build Coastguard Worker`apex_pubkey` is the public key used to sign the file system image. At runtime, 75*33f37583SAndroid Build Coastguard Workerthis key ensures that the downloaded APEX is signed with the same entity that 76*33f37583SAndroid Build Coastguard Workersigns the same APEX in the built-in partitions. 77*33f37583SAndroid Build Coastguard Worker 78*33f37583SAndroid Build Coastguard Worker### APEX manager 79*33f37583SAndroid Build Coastguard Worker 80*33f37583SAndroid Build Coastguard WorkerThe APEX manager (or `apexd`) is a native daemon responsible for verifying, 81*33f37583SAndroid Build Coastguard Workerinstalling, and uninstalling APEX files. This process is launched and is ready 82*33f37583SAndroid Build Coastguard Workerearly in the boot sequence. APEX files are normally pre-installed on the device 83*33f37583SAndroid Build Coastguard Workerunder `/system/apex`. The APEX manager defaults to using these packages if no 84*33f37583SAndroid Build Coastguard Workerupdates are available. 85*33f37583SAndroid Build Coastguard Worker 86*33f37583SAndroid Build Coastguard WorkerThe update sequence of an APEX uses the 87*33f37583SAndroid Build Coastguard Worker[PackageManager class](https://developer.android.com/reference/android/content/pm/PackageManager) 88*33f37583SAndroid Build Coastguard Workerand is as follows. 89*33f37583SAndroid Build Coastguard Worker 90*33f37583SAndroid Build Coastguard Worker1. An APEX file is downloaded via a package installer app, ADB, or other 91*33f37583SAndroid Build Coastguard Worker source. 92*33f37583SAndroid Build Coastguard Worker1. The package manager starts the installation procedure. Upon recognizing that 93*33f37583SAndroid Build Coastguard Worker the file is an APEX, the package manager transfers control to the APEX 94*33f37583SAndroid Build Coastguard Worker manager. 95*33f37583SAndroid Build Coastguard Worker1. The APEX manager verifies the APEX file. 96*33f37583SAndroid Build Coastguard Worker1. If the APEX file is verified, the internal database of the APEX manager is 97*33f37583SAndroid Build Coastguard Worker updated to reflect that the APEX file will be activated at next boot. 98*33f37583SAndroid Build Coastguard Worker1. The requestor of the install receives a broadcast upon successful 99*33f37583SAndroid Build Coastguard Worker verification of the package. 100*33f37583SAndroid Build Coastguard Worker1. To continue the installation, the system automatically reboots the device. 101*33f37583SAndroid Build Coastguard Worker1. At reboot, the APEX manager starts, reads the internal database, and does 102*33f37583SAndroid Build Coastguard Worker the following for each APEX file listed: 103*33f37583SAndroid Build Coastguard Worker 104*33f37583SAndroid Build Coastguard Worker 1. Verifies the APEX file. 105*33f37583SAndroid Build Coastguard Worker 1. Creates a loop device from the APEX file. 106*33f37583SAndroid Build Coastguard Worker 1. Creates a device mapper block device on top of the loop device. 107*33f37583SAndroid Build Coastguard Worker 1. Mounts the device mapper block device onto a unique path (for example, 108*33f37583SAndroid Build Coastguard Worker <code>/apex/<var>name</var>@<var>ver</var></code>). 109*33f37583SAndroid Build Coastguard Worker 110*33f37583SAndroid Build Coastguard WorkerWhen all APEX files listed in the internal database are mounted, the APEX 111*33f37583SAndroid Build Coastguard Workermanager provides a binder service for other system components to query 112*33f37583SAndroid Build Coastguard Workerinformation about the installed APEX files. For example, the other system 113*33f37583SAndroid Build Coastguard Workercomponents can query the list of APEX files installed in the device or query the 114*33f37583SAndroid Build Coastguard Workerexact path where a specific APEX is mounted, so the files can be accessed. 115*33f37583SAndroid Build Coastguard Worker 116*33f37583SAndroid Build Coastguard Worker### APEX files are APK files 117*33f37583SAndroid Build Coastguard Worker 118*33f37583SAndroid Build Coastguard WorkerAPEX files are valid APK files because they are signed zip archives (using the 119*33f37583SAndroid Build Coastguard WorkerAPK signature scheme) containing an `AndroidManifest.xml` file. This allows APEX 120*33f37583SAndroid Build Coastguard Workerfiles to use the infrastructure for APK files, such as a package installer app, 121*33f37583SAndroid Build Coastguard Workerthe signing utility, and the package manager. 122*33f37583SAndroid Build Coastguard Worker 123*33f37583SAndroid Build Coastguard WorkerThe `AndroidManifest.xml` file inside an APEX file is minimal, consisting of the 124*33f37583SAndroid Build Coastguard Workerpackage `name`, `versionCode`, and optional `targetSdkVersion`, `minSdkVersion`, 125*33f37583SAndroid Build Coastguard Workerand `maxSdkVersion` for fine-grained targeting. This information allows APEX 126*33f37583SAndroid Build Coastguard Workerfiles to be delivered via existing channels such as package installer apps and 127*33f37583SAndroid Build Coastguard WorkerADB. 128*33f37583SAndroid Build Coastguard Worker 129*33f37583SAndroid Build Coastguard Worker### File types supported 130*33f37583SAndroid Build Coastguard Worker 131*33f37583SAndroid Build Coastguard WorkerThe APEX format supports these file types: 132*33f37583SAndroid Build Coastguard Worker 133*33f37583SAndroid Build Coastguard Worker- Native shared libs 134*33f37583SAndroid Build Coastguard Worker- Native executables 135*33f37583SAndroid Build Coastguard Worker- JAR files 136*33f37583SAndroid Build Coastguard Worker- Data files 137*33f37583SAndroid Build Coastguard Worker- Config files 138*33f37583SAndroid Build Coastguard Worker 139*33f37583SAndroid Build Coastguard WorkerThe APEX format can only update some of these file types. Whether a file type 140*33f37583SAndroid Build Coastguard Workercan be updated depends on the platform and how stable the interfaces for the 141*33f37583SAndroid Build Coastguard Workerfiles types are defined. 142*33f37583SAndroid Build Coastguard Worker 143*33f37583SAndroid Build Coastguard Worker### Signing 144*33f37583SAndroid Build Coastguard Worker 145*33f37583SAndroid Build Coastguard WorkerAPEX files are signed in two ways. First, the `apex_payload.img` (specifically, 146*33f37583SAndroid Build Coastguard Workerthe vbmeta descriptor appended to `apex_payload.img`) file is signed with a key. 147*33f37583SAndroid Build Coastguard WorkerThen, the entire APEX is signed using the 148*33f37583SAndroid Build Coastguard Worker[APK signature scheme v3](/https://source.android.com/security/apksigning/v3). 149*33f37583SAndroid Build Coastguard WorkerTwo different keys are used in this process. 150*33f37583SAndroid Build Coastguard Worker 151*33f37583SAndroid Build Coastguard WorkerOn the device side, a public key corresponding to the private key used to sign 152*33f37583SAndroid Build Coastguard Workerthe vbmeta descriptor is installed. The APEX manager uses the public key to 153*33f37583SAndroid Build Coastguard Workerverify APEXs that are requested to be installed. Each APEX must be signed with 154*33f37583SAndroid Build Coastguard Workerdifferent keys and is enforced both at build time and runtime. 155*33f37583SAndroid Build Coastguard Worker 156*33f37583SAndroid Build Coastguard Worker### APEX in built-in partitions 157*33f37583SAndroid Build Coastguard Worker 158*33f37583SAndroid Build Coastguard WorkerAPEX files can be located in built-in partitions such as `/system`. The 159*33f37583SAndroid Build Coastguard Workerpartition is already over dm-verity, so the APEX files are mounted directly over 160*33f37583SAndroid Build Coastguard Workerthe loop device. 161*33f37583SAndroid Build Coastguard Worker 162*33f37583SAndroid Build Coastguard WorkerIf an APEX is present in a built-in partition, the APEX can be updated by 163*33f37583SAndroid Build Coastguard Workerproviding an APEX package with the same package name and a higher version code. 164*33f37583SAndroid Build Coastguard WorkerThe new APEX is stored in `/data` and, similar to APKs, the newer version 165*33f37583SAndroid Build Coastguard Workershadows the version already present in the built-in partition. But unlike APKs, 166*33f37583SAndroid Build Coastguard Workerthe newer version of the APEX is only activated after reboot. 167*33f37583SAndroid Build Coastguard Worker 168*33f37583SAndroid Build Coastguard Worker## Kernel requirements 169*33f37583SAndroid Build Coastguard Worker 170*33f37583SAndroid Build Coastguard WorkerTo support APEX mainline modules on an Android device, the following Linux 171*33f37583SAndroid Build Coastguard Workerkernel features are required: the loop driver and dm-verity. The loop driver 172*33f37583SAndroid Build Coastguard Workermounts the file system image in an APEX module and dm-verity verifies the APEX 173*33f37583SAndroid Build Coastguard Workermodule. 174*33f37583SAndroid Build Coastguard Worker 175*33f37583SAndroid Build Coastguard WorkerThe performance of the loop driver and dm-verity is important in achieving good 176*33f37583SAndroid Build Coastguard Workersystem performance when using APEX modules. 177*33f37583SAndroid Build Coastguard Worker 178*33f37583SAndroid Build Coastguard Worker### Supported kernel versions 179*33f37583SAndroid Build Coastguard Worker 180*33f37583SAndroid Build Coastguard WorkerAPEX mainline modules are supported on devices using kernel versions 4.4 or 181*33f37583SAndroid Build Coastguard Workerhigher. New devices launching with Android Q or higher must use kernel version 182*33f37583SAndroid Build Coastguard Worker4.9 or higher to support APEX modules. 183*33f37583SAndroid Build Coastguard Worker 184*33f37583SAndroid Build Coastguard Worker### Required kernel patches 185*33f37583SAndroid Build Coastguard Worker 186*33f37583SAndroid Build Coastguard WorkerThe required kernel patches for supporting APEX modules are included in the 187*33f37583SAndroid Build Coastguard WorkerAndroid common tree. To get the patches to support APEX, use the latest version 188*33f37583SAndroid Build Coastguard Workerof the Android common tree. 189*33f37583SAndroid Build Coastguard Worker 190*33f37583SAndroid Build Coastguard Worker#### Kernel version 4.4 191*33f37583SAndroid Build Coastguard Worker 192*33f37583SAndroid Build Coastguard WorkerThis version is only supported for devices that are upgraded from Android 9 to 193*33f37583SAndroid Build Coastguard WorkerAndroid Q and want to support APEX modules. To get the required patches, a 194*33f37583SAndroid Build Coastguard Workerdown-merge from the `android-4.4` branch is strongly recommended. The following 195*33f37583SAndroid Build Coastguard Workeris a list of the required individual patches for kernel version 4.4. 196*33f37583SAndroid Build Coastguard Worker 197*33f37583SAndroid Build Coastguard Worker- UPSTREAM: loop: add ioctl for changing logical block size 198*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777013){: .external}) 199*33f37583SAndroid Build Coastguard Worker- BACKPORT: block/loop: set hw_sectors 200*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777014/7){: .external}) 201*33f37583SAndroid Build Coastguard Worker- UPSTREAM: loop: Add LOOP_SET_BLOCK_SIZE in compat ioctl 202*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777015/7){: .external}) 203*33f37583SAndroid Build Coastguard Worker- ANDROID: mnt: Fix next_descendent 204*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/405314){: .external}) 205*33f37583SAndroid Build Coastguard Worker- ANDROID: mnt: remount should propagate to slaves of slaves 206*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/320406){: .external}) 207*33f37583SAndroid Build Coastguard Worker- ANDROID: mnt: Propagate remount correctly 208*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/928253){: .external}) 209*33f37583SAndroid Build Coastguard Worker- Revert "ANDROID: dm verity: add minimum prefetch size" 210*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/867875){: .external}) 211*33f37583SAndroid Build Coastguard Worker- UPSTREAM: loop: drop caches if offset or block_size are changed 212*33f37583SAndroid Build Coastguard Worker ([4.4](https://android-review.googlesource.com/c/kernel/common/+/854265){: .external}) 213*33f37583SAndroid Build Coastguard Worker 214*33f37583SAndroid Build Coastguard Worker#### Kernel versions 4.9/4.14/4.19 215*33f37583SAndroid Build Coastguard Worker 216*33f37583SAndroid Build Coastguard WorkerTo get the required patches for kernel versions 4.9/4.14/4.19, down-merge from 217*33f37583SAndroid Build Coastguard Workerthe `android-common` branch. 218*33f37583SAndroid Build Coastguard Worker 219*33f37583SAndroid Build Coastguard Worker### Required kernel configuration options 220*33f37583SAndroid Build Coastguard Worker 221*33f37583SAndroid Build Coastguard WorkerThe following list shows the base configuration requirements for supporting APEX 222*33f37583SAndroid Build Coastguard Workermodules that were introduced in Android Q. The items with an asterisk (\*) are 223*33f37583SAndroid Build Coastguard Workerexisting requirements from Android 9 and lower. 224*33f37583SAndroid Build Coastguard Worker 225*33f37583SAndroid Build Coastguard Worker``` 226*33f37583SAndroid Build Coastguard Worker(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices) 227*33f37583SAndroid Build Coastguard WorkerCONFIG_BLK_DEV_LOOP=Y # for loop device support 228*33f37583SAndroid Build Coastguard WorkerCONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices 229*33f37583SAndroid Build Coastguard Worker(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity 230*33f37583SAndroid Build Coastguard Worker(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity 231*33f37583SAndroid Build Coastguard WorkerCONFIG_DM_VERITY=Y # DM-verity support 232*33f37583SAndroid Build Coastguard Worker``` 233*33f37583SAndroid Build Coastguard Worker 234*33f37583SAndroid Build Coastguard Worker### Kernel command line parameter requirements 235*33f37583SAndroid Build Coastguard Worker 236*33f37583SAndroid Build Coastguard WorkerTo support APEX, make sure the kernel command line parameters meet the following 237*33f37583SAndroid Build Coastguard Workerrequirements. 238*33f37583SAndroid Build Coastguard Worker 239*33f37583SAndroid Build Coastguard Worker- `loop.max_loop` must NOT be set 240*33f37583SAndroid Build Coastguard Worker- `loop.max_part` must be <= 7 241*33f37583SAndroid Build Coastguard Worker 242*33f37583SAndroid Build Coastguard Worker## Building an APEX 243*33f37583SAndroid Build Coastguard Worker 244*33f37583SAndroid Build Coastguard WorkerNote: Because the implementation details for APEX are still under development, 245*33f37583SAndroid Build Coastguard Workerthe content in this section is subject to change. 246*33f37583SAndroid Build Coastguard Worker 247*33f37583SAndroid Build Coastguard WorkerThis section describes how to build an APEX using the Android build system. The 248*33f37583SAndroid Build Coastguard Workerfollowing is an example of `Android.bp` for an APEX named `apex.test`. 249*33f37583SAndroid Build Coastguard Worker 250*33f37583SAndroid Build Coastguard Worker``` 251*33f37583SAndroid Build Coastguard Workerapex { 252*33f37583SAndroid Build Coastguard Worker name: "apex.test", 253*33f37583SAndroid Build Coastguard Worker manifest: "apex_manifest.json", 254*33f37583SAndroid Build Coastguard Worker file_contexts: "file_contexts", 255*33f37583SAndroid Build Coastguard Worker // libc.so and libcutils.so are included in the apex 256*33f37583SAndroid Build Coastguard Worker native_shared_libs: ["libc", "libcutils"], 257*33f37583SAndroid Build Coastguard Worker binaries: ["vold"], 258*33f37583SAndroid Build Coastguard Worker java_libs: ["core-all"], 259*33f37583SAndroid Build Coastguard Worker prebuilts: ["my_prebuilt"], 260*33f37583SAndroid Build Coastguard Worker compile_multilib: "both", 261*33f37583SAndroid Build Coastguard Worker key: "apex.test.key", 262*33f37583SAndroid Build Coastguard Worker certificate: "platform", 263*33f37583SAndroid Build Coastguard Worker} 264*33f37583SAndroid Build Coastguard Worker``` 265*33f37583SAndroid Build Coastguard Worker 266*33f37583SAndroid Build Coastguard Worker`apex_manifest.json` example: 267*33f37583SAndroid Build Coastguard Worker 268*33f37583SAndroid Build Coastguard Worker``` 269*33f37583SAndroid Build Coastguard Worker{ 270*33f37583SAndroid Build Coastguard Worker "name": "com.android.example.apex", 271*33f37583SAndroid Build Coastguard Worker "version": 1 272*33f37583SAndroid Build Coastguard Worker} 273*33f37583SAndroid Build Coastguard Worker``` 274*33f37583SAndroid Build Coastguard Worker 275*33f37583SAndroid Build Coastguard Worker`file_contexts` example: 276*33f37583SAndroid Build Coastguard Worker 277*33f37583SAndroid Build Coastguard Worker``` 278*33f37583SAndroid Build Coastguard Worker(/.*)? u:object_r:system_file:s0 279*33f37583SAndroid Build Coastguard Worker/sub(/.*)? u:object_r:sub_file:s0 280*33f37583SAndroid Build Coastguard Worker/sub/file3 u:object_r:file3_file:s0 281*33f37583SAndroid Build Coastguard Worker``` 282*33f37583SAndroid Build Coastguard Worker 283*33f37583SAndroid Build Coastguard Worker#### File types and locations in APEX 284*33f37583SAndroid Build Coastguard Worker 285*33f37583SAndroid Build Coastguard WorkerFile type | Location in APEX 286*33f37583SAndroid Build Coastguard Worker---------------- | ---------------------------------------------------------- 287*33f37583SAndroid Build Coastguard WorkerShared libraries | `/lib` and `/lib64` (`/lib/arm` for translated arm in x86) 288*33f37583SAndroid Build Coastguard WorkerExecutables | `/bin` 289*33f37583SAndroid Build Coastguard WorkerJava libraries | `/javalib` 290*33f37583SAndroid Build Coastguard WorkerPrebuilts | `/etc` 291*33f37583SAndroid Build Coastguard Worker 292*33f37583SAndroid Build Coastguard Worker### Transitive dependencies 293*33f37583SAndroid Build Coastguard Worker 294*33f37583SAndroid Build Coastguard WorkerAPEX files automatically include transitive dependencies of native shared libs 295*33f37583SAndroid Build Coastguard Workeror executables. For example, if `libFoo` depends on `libBar`, the two libs are 296*33f37583SAndroid Build Coastguard Workerincluded when only `libFoo` is listed in the `native_shared_libs` property. 297*33f37583SAndroid Build Coastguard Worker 298*33f37583SAndroid Build Coastguard Worker### Handling multiple ABIs 299*33f37583SAndroid Build Coastguard Worker 300*33f37583SAndroid Build Coastguard WorkerInstall the `native_shared_libs` property for both primary and secondary 301*33f37583SAndroid Build Coastguard Workerapplication binary interfaces (ABIs) of the device. If an APEX targets devices 302*33f37583SAndroid Build Coastguard Workerwith a single ABI (that is, 32 bit only or 64 bit only), only libraries with the 303*33f37583SAndroid Build Coastguard Workercorresponding ABI are installed. 304*33f37583SAndroid Build Coastguard Worker 305*33f37583SAndroid Build Coastguard WorkerInstall the `binaries` property only for the primary ABI of the device as 306*33f37583SAndroid Build Coastguard Workerdescribed below: 307*33f37583SAndroid Build Coastguard Worker 308*33f37583SAndroid Build Coastguard Worker- If the device is 32 bit only, only the 32-bit variant of the binary is 309*33f37583SAndroid Build Coastguard Worker installed. 310*33f37583SAndroid Build Coastguard Worker- If the device supports both 32/64 ABIs, but with 311*33f37583SAndroid Build Coastguard Worker `TARGET_PREFER_32_BIT_EXECUTABLES=true`, then only the 32-bit variant of the 312*33f37583SAndroid Build Coastguard Worker binary is installed. 313*33f37583SAndroid Build Coastguard Worker- If the device is 64 bit only, then only the 64-bit variant of the binary is 314*33f37583SAndroid Build Coastguard Worker installed. 315*33f37583SAndroid Build Coastguard Worker- If the device supports both 32/64 ABIs, but without 316*33f37583SAndroid Build Coastguard Worker TARGET_PREFER_32_BIT_EXECUTABLES`=true`, then only the 64-bit variant of the 317*33f37583SAndroid Build Coastguard Worker binary is installed. 318*33f37583SAndroid Build Coastguard Worker 319*33f37583SAndroid Build Coastguard WorkerTo add fine-grained control over the ABIs of the native libraries and binaries, 320*33f37583SAndroid Build Coastguard Workeruse the 321*33f37583SAndroid Build Coastguard Worker`multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]` 322*33f37583SAndroid Build Coastguard Workerproperties. 323*33f37583SAndroid Build Coastguard Worker 324*33f37583SAndroid Build Coastguard Worker- `first`: Matches the primary ABI of the device. This is the default for 325*33f37583SAndroid Build Coastguard Worker binaries. 326*33f37583SAndroid Build Coastguard Worker- `lib32`: Matches the 32-bit ABI of the device, if supported. 327*33f37583SAndroid Build Coastguard Worker- `lib64`: Matches the 64-bit ABI of the device, it supported. 328*33f37583SAndroid Build Coastguard Worker- `prefer32`: Matches the 32-bit ABI of the device, if supported. If the 329*33f37583SAndroid Build Coastguard Worker 32-bit ABI isn't supported, matches the 64-bit ABI. 330*33f37583SAndroid Build Coastguard Worker- `both`: Matches both ABIs. This is the default for 331*33f37583SAndroid Build Coastguard Worker `native_shared_libraries`. 332*33f37583SAndroid Build Coastguard Worker 333*33f37583SAndroid Build Coastguard WorkerThe `java`, `libraries`, and `prebuilts` properties are ABI-agnostic. 334*33f37583SAndroid Build Coastguard Worker 335*33f37583SAndroid Build Coastguard WorkerThis example is for a device that supports 32/64 and doesn't prefer 32: 336*33f37583SAndroid Build Coastguard Worker 337*33f37583SAndroid Build Coastguard Worker``` 338*33f37583SAndroid Build Coastguard Workerapex { 339*33f37583SAndroid Build Coastguard Worker // other properties are omitted 340*33f37583SAndroid Build Coastguard Worker native_shared_libs: ["libFoo"], // installed for 32 and 64 341*33f37583SAndroid Build Coastguard Worker binaries: ["exec1"], // installed for 64, but not for 32 342*33f37583SAndroid Build Coastguard Worker multilib: { 343*33f37583SAndroid Build Coastguard Worker first: { 344*33f37583SAndroid Build Coastguard Worker native_shared_libs: ["libBar"], // installed for 64, but not for 32 345*33f37583SAndroid Build Coastguard Worker binaries: ["exec2"], // same as binaries without multilib.first 346*33f37583SAndroid Build Coastguard Worker }, 347*33f37583SAndroid Build Coastguard Worker both: { 348*33f37583SAndroid Build Coastguard Worker native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib 349*33f37583SAndroid Build Coastguard Worker binaries: ["exec3"], // installed for 32 and 64 350*33f37583SAndroid Build Coastguard Worker }, 351*33f37583SAndroid Build Coastguard Worker prefer32: { 352*33f37583SAndroid Build Coastguard Worker native_shared_libs: ["libX"], // installed for 32, but not for 64 353*33f37583SAndroid Build Coastguard Worker }, 354*33f37583SAndroid Build Coastguard Worker lib64: { 355*33f37583SAndroid Build Coastguard Worker native_shared_libs: ["libY"], // installed for 64, but not for 32 356*33f37583SAndroid Build Coastguard Worker }, 357*33f37583SAndroid Build Coastguard Worker }, 358*33f37583SAndroid Build Coastguard Worker} 359*33f37583SAndroid Build Coastguard Worker``` 360*33f37583SAndroid Build Coastguard Worker 361*33f37583SAndroid Build Coastguard Worker### vbmeta signing 362*33f37583SAndroid Build Coastguard Worker 363*33f37583SAndroid Build Coastguard WorkerSign each APEX with different keys. When a new key is required, create a 364*33f37583SAndroid Build Coastguard Workerpublic-private key pair and make an `apex_key` module. Use the `key` property to 365*33f37583SAndroid Build Coastguard Workersign the APEX using the key. The public key is automatically included in the 366*33f37583SAndroid Build Coastguard WorkerAPEX with the name `avb_pubkey`. 367*33f37583SAndroid Build Coastguard Worker 368*33f37583SAndroid Build Coastguard WorkerCreate an rsa key pair. 369*33f37583SAndroid Build Coastguard Worker 370*33f37583SAndroid Build Coastguard Worker``` 371*33f37583SAndroid Build Coastguard Worker$ openssl genrsa -out foo.pem 4096 372*33f37583SAndroid Build Coastguard Worker``` 373*33f37583SAndroid Build Coastguard Worker 374*33f37583SAndroid Build Coastguard WorkerExtract the public key from the key pair. 375*33f37583SAndroid Build Coastguard Worker 376*33f37583SAndroid Build Coastguard Worker``` 377*33f37583SAndroid Build Coastguard Worker$ avbtool extract_public_key --key foo.pem --output foo.avbpubkey 378*33f37583SAndroid Build Coastguard Worker``` 379*33f37583SAndroid Build Coastguard Worker 380*33f37583SAndroid Build Coastguard WorkerIn Android.bp: 381*33f37583SAndroid Build Coastguard Worker 382*33f37583SAndroid Build Coastguard Worker``` 383*33f37583SAndroid Build Coastguard Workerapex_key { 384*33f37583SAndroid Build Coastguard Worker name: "apex.test.key", 385*33f37583SAndroid Build Coastguard Worker public_key: "foo.avbpubkey", 386*33f37583SAndroid Build Coastguard Worker private_key: "foo.pem", 387*33f37583SAndroid Build Coastguard Worker} 388*33f37583SAndroid Build Coastguard Worker``` 389*33f37583SAndroid Build Coastguard Worker 390*33f37583SAndroid Build Coastguard WorkerIn the above example, the name of the public key (`foo`) becomes the ID of the 391*33f37583SAndroid Build Coastguard Workerkey. The ID of the key used to sign an APEX is written in the APEX. At runtime, 392*33f37583SAndroid Build Coastguard Worker`apexd` verifies the APEX using a public key with the same ID in the device. 393*33f37583SAndroid Build Coastguard Worker 394*33f37583SAndroid Build Coastguard Worker### ZIP signing 395*33f37583SAndroid Build Coastguard Worker 396*33f37583SAndroid Build Coastguard WorkerSign APEXs in the same way as APKs. Sign APEXs twice, once for the mini file 397*33f37583SAndroid Build Coastguard Workersystem (`apex_payload.img` file) and once for the entire file. 398*33f37583SAndroid Build Coastguard Worker 399*33f37583SAndroid Build Coastguard WorkerTo sign an APEX at the file-level, set the `certificate` property in one of 400*33f37583SAndroid Build Coastguard Workerthese three ways: 401*33f37583SAndroid Build Coastguard Worker 402*33f37583SAndroid Build Coastguard Worker- Not set: If no value is set, the APEX is signed with the certificate located 403*33f37583SAndroid Build Coastguard Worker at `PRODUCT_DEFAULT_DEV_CERTIFICATE`. If no flag is set, the path defaults 404*33f37583SAndroid Build Coastguard Worker to `build/target/product/security/testkey`. 405*33f37583SAndroid Build Coastguard Worker- `<name>`: The APEX is signed with the `<name>` certificate in the same 406*33f37583SAndroid Build Coastguard Worker directory as `PRODUCT_DEFAULT_DEV_CERTIFICATE`. 407*33f37583SAndroid Build Coastguard Worker- `:<name>`: The APEX is signed with the certificate that is defined by the 408*33f37583SAndroid Build Coastguard Worker Soong module named `<name>`. The certificate module can be defined as 409*33f37583SAndroid Build Coastguard Worker follows. 410*33f37583SAndroid Build Coastguard Worker 411*33f37583SAndroid Build Coastguard Worker``` 412*33f37583SAndroid Build Coastguard Workerandroid_app_certificate { 413*33f37583SAndroid Build Coastguard Worker name: "my_key_name", 414*33f37583SAndroid Build Coastguard Worker certificate: "dir/cert", 415*33f37583SAndroid Build Coastguard Worker // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key) 416*33f37583SAndroid Build Coastguard Worker} 417*33f37583SAndroid Build Coastguard Worker``` 418*33f37583SAndroid Build Coastguard Worker 419*33f37583SAndroid Build Coastguard WorkerNote: The `key` and `certificate` values do NOT need to be derived from the same 420*33f37583SAndroid Build Coastguard Workerpublic/private key pairs. APK signing (specified by `certificate`) is required 421*33f37583SAndroid Build Coastguard Workerbecause an APEX is an APK. 422*33f37583SAndroid Build Coastguard Worker 423*33f37583SAndroid Build Coastguard Worker## Installing an APEX 424*33f37583SAndroid Build Coastguard Worker 425*33f37583SAndroid Build Coastguard WorkerTo install an APEX, use ADB. 426*33f37583SAndroid Build Coastguard Worker 427*33f37583SAndroid Build Coastguard Worker``` 428*33f37583SAndroid Build Coastguard Worker$ adb install apex_file_name 429*33f37583SAndroid Build Coastguard Worker$ adb reboot 430*33f37583SAndroid Build Coastguard Worker``` 431*33f37583SAndroid Build Coastguard Worker 432*33f37583SAndroid Build Coastguard Worker## Using an APEX 433*33f37583SAndroid Build Coastguard Worker 434*33f37583SAndroid Build Coastguard WorkerAfter reboot, the APEX is mounted at the `/apex/<apex_name>@<version>` 435*33f37583SAndroid Build Coastguard Workerdirectory. Multiple versions of the same APEX can be mounted at the same time. 436*33f37583SAndroid Build Coastguard WorkerAmong the mount paths, the one that corresponds to the latest version is 437*33f37583SAndroid Build Coastguard Workerbind-mounted at `/apex/<apex_name>`. 438*33f37583SAndroid Build Coastguard Worker 439*33f37583SAndroid Build Coastguard WorkerClients can use the bind-mounted path to read or execute files from APEX. 440*33f37583SAndroid Build Coastguard Worker 441*33f37583SAndroid Build Coastguard WorkerAPEXs are typically used as follows: 442*33f37583SAndroid Build Coastguard Worker 443*33f37583SAndroid Build Coastguard Worker1. An OEM or ODM preloads an APEX under `/system/apex` when the device is 444*33f37583SAndroid Build Coastguard Worker shipped. 445*33f37583SAndroid Build Coastguard Worker1. Files in the APEX are accessed via the `/apex/<apex_name>/` path. 446*33f37583SAndroid Build Coastguard Worker1. When an updated version of the APEX is installed in `/data/apex`, the path 447*33f37583SAndroid Build Coastguard Worker points to the new APEX after reboot. 448*33f37583SAndroid Build Coastguard Worker 449*33f37583SAndroid Build Coastguard Worker### Updating a service with an APEX 450*33f37583SAndroid Build Coastguard Worker 451*33f37583SAndroid Build Coastguard WorkerTo update a service using an APEX: 452*33f37583SAndroid Build Coastguard Worker 453*33f37583SAndroid Build Coastguard Worker1. Mark the service in the system partition as updatable. Add the option 454*33f37583SAndroid Build Coastguard Worker `updatable` to the service definition. 455*33f37583SAndroid Build Coastguard Worker 456*33f37583SAndroid Build Coastguard Worker ``` 457*33f37583SAndroid Build Coastguard Worker /system/etc/init/myservice.rc: 458*33f37583SAndroid Build Coastguard Worker 459*33f37583SAndroid Build Coastguard Worker service myservice /system/bin/myservice 460*33f37583SAndroid Build Coastguard Worker class core 461*33f37583SAndroid Build Coastguard Worker user system 462*33f37583SAndroid Build Coastguard Worker ... 463*33f37583SAndroid Build Coastguard Worker updatable 464*33f37583SAndroid Build Coastguard Worker ``` 465*33f37583SAndroid Build Coastguard Worker 466*33f37583SAndroid Build Coastguard Worker1. Create a new `.rc` file for the updated service. Use the `override` option 467*33f37583SAndroid Build Coastguard Worker to redefine the existing service. 468*33f37583SAndroid Build Coastguard Worker 469*33f37583SAndroid Build Coastguard Worker ``` 470*33f37583SAndroid Build Coastguard Worker /apex/my.apex@1/etc/init.rc: 471*33f37583SAndroid Build Coastguard Worker 472*33f37583SAndroid Build Coastguard Worker service myservice /apex/my.apex@1/bin/myservice 473*33f37583SAndroid Build Coastguard Worker class core 474*33f37583SAndroid Build Coastguard Worker user system 475*33f37583SAndroid Build Coastguard Worker ... 476*33f37583SAndroid Build Coastguard Worker override 477*33f37583SAndroid Build Coastguard Worker ``` 478*33f37583SAndroid Build Coastguard Worker 479*33f37583SAndroid Build Coastguard WorkerService definitions can only be defined in the `.rc` file of an APEX. Action 480*33f37583SAndroid Build Coastguard Workertriggers aren't supported in APEXs. 481*33f37583SAndroid Build Coastguard Worker 482*33f37583SAndroid Build Coastguard WorkerIf a service marked as updatable starts before the APEXs are activated, the 483*33f37583SAndroid Build Coastguard Workerstart is delayed until the activation of the APEXs is complete. 484*33f37583SAndroid Build Coastguard Worker 485*33f37583SAndroid Build Coastguard Worker## Configuring system to support APEX updates 486*33f37583SAndroid Build Coastguard Worker 487*33f37583SAndroid Build Coastguard WorkerInherit `updatable_apex.mk`. 488*33f37583SAndroid Build Coastguard Worker 489*33f37583SAndroid Build Coastguard Worker``` 490*33f37583SAndroid Build Coastguard Worker<device.mk>: 491*33f37583SAndroid Build Coastguard Worker 492*33f37583SAndroid Build Coastguard Worker$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk) 493*33f37583SAndroid Build Coastguard Worker``` 494*33f37583SAndroid Build Coastguard Worker 495*33f37583SAndroid Build Coastguard Worker## Compressed apexes {#compressed-apex} 496*33f37583SAndroid Build Coastguard Worker 497*33f37583SAndroid Build Coastguard WorkerAPEX compression is a new feature introduced in Android S. Its main purpose is 498*33f37583SAndroid Build Coastguard Workerto reduce the storage impact of updatable APEX packages: after an update to an 499*33f37583SAndroid Build Coastguard WorkerAPEX is installed, its pre-installed version is not used anymore, and space that 500*33f37583SAndroid Build Coastguard Workeris taken by it effectively becomes a dead weight. 501*33f37583SAndroid Build Coastguard Worker 502*33f37583SAndroid Build Coastguard WorkerAPEX compression minimizes the storage impact by using a highly-compressed 503*33f37583SAndroid Build Coastguard Workerset of APEX files on read-only partitions (e.g. `/system`). In Android S a 504*33f37583SAndroid Build Coastguard WorkerDEFLATE zip compression is used. 505*33f37583SAndroid Build Coastguard Worker 506*33f37583SAndroid Build Coastguard WorkerNote: compression doesn't provide any optimization in the following scenarios: 507*33f37583SAndroid Build Coastguard Worker 508*33f37583SAndroid Build Coastguard Worker* Bootstrap apexes that are required to be mounted very early in the boot 509*33f37583SAndroid Build Coastguard Worker sequence. List of bootstrap apexes is configured in `kBootstrapApexes` 510*33f37583SAndroid Build Coastguard Worker constant in `system/apex/apexd/apexd.cpp`. 511*33f37583SAndroid Build Coastguard Worker* Non-updatable apexes. Compression is only beneficial in case an updated 512*33f37583SAndroid Build Coastguard Worker version of an apex is installed on `/data partition`. 513*33f37583SAndroid Build Coastguard Worker Full list of updatable apexes is available at 514*33f37583SAndroid Build Coastguard Worker https://source.android.com/devices/architecture/modular-system. 515*33f37583SAndroid Build Coastguard Worker* Dynamic shared libs apexes. Since `apexd` will always activate both versions 516*33f37583SAndroid Build Coastguard Worker of such apexes (pre-installed and upgraded), compressing them doesn't provide 517*33f37583SAndroid Build Coastguard Worker any value. 518*33f37583SAndroid Build Coastguard Worker 519*33f37583SAndroid Build Coastguard Worker### Compressed APEX file format 520*33f37583SAndroid Build Coastguard Worker 521*33f37583SAndroid Build Coastguard WorkerThis is the format of a compressed APEX file. 522*33f37583SAndroid Build Coastguard Worker 523*33f37583SAndroid Build Coastguard Worker 524*33f37583SAndroid Build Coastguard Worker 525*33f37583SAndroid Build Coastguard Worker**Figure 2.** Compressed APEX file format 526*33f37583SAndroid Build Coastguard Worker 527*33f37583SAndroid Build Coastguard WorkerAt the top level, a compressed APEX file is a zip file containing the original apex in deflated 528*33f37583SAndroid Build Coastguard Workerform with compression level of 9 and other files stored uncompressed. 529*33f37583SAndroid Build Coastguard Worker 530*33f37583SAndroid Build Coastguard WorkerThe four files in an APEX file are: 531*33f37583SAndroid Build Coastguard Worker 532*33f37583SAndroid Build Coastguard Worker* `original_apex`: deflated with compression level of 9 533*33f37583SAndroid Build Coastguard Worker* `apex_manifest.pb`: stored only 534*33f37583SAndroid Build Coastguard Worker* `AndroidManifest.xml`: stored only 535*33f37583SAndroid Build Coastguard Worker* `apex_pubkey`: stored only 536*33f37583SAndroid Build Coastguard Worker 537*33f37583SAndroid Build Coastguard Worker 538*33f37583SAndroid Build Coastguard Worker`original_apex` is the original uncompressed [APEX file](#apex-format). 539*33f37583SAndroid Build Coastguard Worker 540*33f37583SAndroid Build Coastguard Worker`apex_manifest.pb` `AndroidManifest.xml` `apex_pubkey` are copies of the 541*33f37583SAndroid Build Coastguard Workercorresponding files from `original_apex`. 542*33f37583SAndroid Build Coastguard Worker 543*33f37583SAndroid Build Coastguard Worker 544*33f37583SAndroid Build Coastguard Worker### Building compressed apex 545*33f37583SAndroid Build Coastguard Worker 546*33f37583SAndroid Build Coastguard WorkerCompressed apex can be built using `apex_compression_tool.py` located at 547*33f37583SAndroid Build Coastguard Worker`system/apex/tools`. 548*33f37583SAndroid Build Coastguard Worker 549*33f37583SAndroid Build Coastguard WorkerNote: the outer apk container of the produced compressed apex file won't be 550*33f37583SAndroid Build Coastguard Workerautomatically signed. You will need to manually sign it with using the correct 551*33f37583SAndroid Build Coastguard Workercertificate. See [Signing Builds for Release]( 552*33f37583SAndroid Build Coastguard Workerhttps://source.android.com/devices/tech/ota/sign_builds#apex-signing-key-replacement). 553*33f37583SAndroid Build Coastguard Worker 554*33f37583SAndroid Build Coastguard WorkerThere are a few different parameters related to APEX compression available in 555*33f37583SAndroid Build Coastguard Workerthe build system. 556*33f37583SAndroid Build Coastguard Worker 557*33f37583SAndroid Build Coastguard WorkerIn `Android.bp` whether an apex is compressible is controlled by `compressible` 558*33f37583SAndroid Build Coastguard Workerproperty: 559*33f37583SAndroid Build Coastguard Worker 560*33f37583SAndroid Build Coastguard Worker``` 561*33f37583SAndroid Build Coastguard Workerapex { 562*33f37583SAndroid Build Coastguard Worker name: "apex.test", 563*33f37583SAndroid Build Coastguard Worker manifest: "apex_manifest.json", 564*33f37583SAndroid Build Coastguard Worker file_contexts: "file_contexts", 565*33f37583SAndroid Build Coastguard Worker compressible: true, 566*33f37583SAndroid Build Coastguard Worker} 567*33f37583SAndroid Build Coastguard Worker``` 568*33f37583SAndroid Build Coastguard Worker 569*33f37583SAndroid Build Coastguard WorkerNote: this only serves as a hint to build system that this apex can be 570*33f37583SAndroid Build Coastguard Workercompressed. Such property is required due to the fact that not all apexes are 571*33f37583SAndroid Build Coastguard Workercompressible as mentioned in the [section above](#compressed-apex). 572*33f37583SAndroid Build Coastguard Worker 573*33f37583SAndroid Build Coastguard WorkerTODO(b/183208430): add docs on how this works for prebuilts. 574*33f37583SAndroid Build Coastguard Worker 575*33f37583SAndroid Build Coastguard WorkerA `PRODUCT_COMPRESSED_APEX` product flag is used to control whether a system 576*33f37583SAndroid Build Coastguard Workerimage built from source should contain compressed apexes or not. 577*33f37583SAndroid Build Coastguard Worker 578*33f37583SAndroid Build Coastguard WorkerFor local experimentation you can force a build to compress apexes by setting 579*33f37583SAndroid Build Coastguard Worker`OVERRIDE_PRODUCT_COMPRESSED_APEX=true`. 580*33f37583SAndroid Build Coastguard Worker 581*33f37583SAndroid Build Coastguard WorkerCompressed APEX files generated by the build system will have `.capex` 582*33f37583SAndroid Build Coastguard Workerextension. It makes it easier to distinguish between compressed and uncompressed 583*33f37583SAndroid Build Coastguard Workerversions of an APEX. 584*33f37583SAndroid Build Coastguard Worker 585*33f37583SAndroid Build Coastguard Worker### Supported compression algorithms 586*33f37583SAndroid Build Coastguard Worker 587*33f37583SAndroid Build Coastguard WorkerAndroid S only supports deflate zip compression. 588*33f37583SAndroid Build Coastguard Worker 589*33f37583SAndroid Build Coastguard Worker### Activating compressed apex during boot 590*33f37583SAndroid Build Coastguard Worker 591*33f37583SAndroid Build Coastguard WorkerBefore activating a compressed APEX, `original_apex` inside it will be 592*33f37583SAndroid Build Coastguard Workerdecompressed into `/data/apex/decompressed` directory. The resulting 593*33f37583SAndroid Build Coastguard Workerdecompressed APEX will be hard linked to the `/data/apex/active` directory. 594*33f37583SAndroid Build Coastguard Worker 595*33f37583SAndroid Build Coastguard WorkerNote: because of the hard link step above, it's important that files under 596*33f37583SAndroid Build Coastguard Worker`/data/apex/decompressed` have the same SELinux label as files under 597*33f37583SAndroid Build Coastguard Worker`/data/apex/active`. 598*33f37583SAndroid Build Coastguard Worker 599*33f37583SAndroid Build Coastguard WorkerConsider following example as an illustration of the process described above. 600*33f37583SAndroid Build Coastguard Worker 601*33f37583SAndroid Build Coastguard WorkerLet's assume that `/system/apex/com.android.foo.capex` is a compressed APEX 602*33f37583SAndroid Build Coastguard Workerbeing activated, and it's `versionCode` is `37`. 603*33f37583SAndroid Build Coastguard Worker 604*33f37583SAndroid Build Coastguard Worker1. First `original_apex` inside `/system/apex/com.android.foo.capex` is 605*33f37583SAndroid Build Coastguard Worker decompressed into `/data/apex/decompressed/com.android.foo@37.apex`. 606*33f37583SAndroid Build Coastguard Worker2. After that `restorecon /data/apex/decompressed/com.android.foo@37.apex` is 607*33f37583SAndroid Build Coastguard Worker performed to make sure that it has a correct SELinux label. 608*33f37583SAndroid Build Coastguard Worker3. Verification checks are performed on 609*33f37583SAndroid Build Coastguard Worker `/data/apex/decompressed/com.android.foo@37.apex` to ensure it's validity: 610*33f37583SAndroid Build Coastguard Worker * `apexd` checks that public key bundled in 611*33f37583SAndroid Build Coastguard Worker `/data/apex/decompressed/com.android.foo@37.apex` is equal to the one 612*33f37583SAndroid Build Coastguard Worker bundled in `/system/apex/com.android.foo.capex` 613*33f37583SAndroid Build Coastguard Worker4. Next `/data/apex/decompressed/com.android.foo@37.apex` is hard linked to 614*33f37583SAndroid Build Coastguard Worker `/data/apex/active/com.android.foo@37.apex`. 615*33f37583SAndroid Build Coastguard Worker5. Finally, regular activation logic for uncompressed APEX files is performed 616*33f37583SAndroid Build Coastguard Worker for `/data/apex/active/com.android.foo@37.apex`. 617*33f37583SAndroid Build Coastguard Worker 618*33f37583SAndroid Build Coastguard WorkerFor more information see implementation of `OnStart` function in 619*33f37583SAndroid Build Coastguard Worker`system/apex/apexd/apexd.cpp`. 620*33f37583SAndroid Build Coastguard Worker 621*33f37583SAndroid Build Coastguard Worker### Interaction with OTA 622*33f37583SAndroid Build Coastguard Worker 623*33f37583SAndroid Build Coastguard WorkerCompressed APEX files have some implications on the OTA delivery and 624*33f37583SAndroid Build Coastguard Workerapplication. Since an OTA might contain a compressed APEX file with higher 625*33f37583SAndroid Build Coastguard Workerversion compared to what is currently active on the device, some free space must 626*33f37583SAndroid Build Coastguard Workerbe reserved before rebooting a device to apply an OTA. 627*33f37583SAndroid Build Coastguard Worker 628*33f37583SAndroid Build Coastguard WorkerTo help OTA system, two new binder APIs are exposed by apexd: 629*33f37583SAndroid Build Coastguard Worker 630*33f37583SAndroid Build Coastguard Worker* `calculateSizeForCompressedApex` - calculates size required for decompressing 631*33f37583SAndroid Build Coastguard Worker APEX files in OTA package. It can be used to check if device has enough space 632*33f37583SAndroid Build Coastguard Worker before downloading an OTA. 633*33f37583SAndroid Build Coastguard Worker* `reserveSpaceForCompressedApex` - reserves space on the disk that in the 634*33f37583SAndroid Build Coastguard Worker future will be used by apexd for decompression of compressed APEX files inside 635*33f37583SAndroid Build Coastguard Worker the OTA package. 636*33f37583SAndroid Build Coastguard Worker 637*33f37583SAndroid Build Coastguard Worker 638*33f37583SAndroid Build Coastguard WorkerIn case of A/B OTA, `apexd` will attempt decompression in the background as part 639*33f37583SAndroid Build Coastguard Workerof the postinstall OTA routine. If decompression fails, `apexd` will fallback to 640*33f37583SAndroid Build Coastguard Workerdecompressing during the boot that applies the OTA. 641*33f37583SAndroid Build Coastguard Worker 642*33f37583SAndroid Build Coastguard Worker## Alternatives considered when developing APEX 643*33f37583SAndroid Build Coastguard Worker 644*33f37583SAndroid Build Coastguard WorkerHere are some options that we considered when designing the APEX file format, 645*33f37583SAndroid Build Coastguard Workerand why we included or excluded them. 646*33f37583SAndroid Build Coastguard Worker 647*33f37583SAndroid Build Coastguard Worker### Regular package management systems 648*33f37583SAndroid Build Coastguard Worker 649*33f37583SAndroid Build Coastguard WorkerLinux distributions have package management systems like `dpkg` and `rpm`, which 650*33f37583SAndroid Build Coastguard Workerare powerful, mature and robust. However, they weren't adopted for APEX because 651*33f37583SAndroid Build Coastguard Workerthey can't protect the packages after installation. Verification is done only 652*33f37583SAndroid Build Coastguard Workerwhen packages are being installed. Attackers can break the integrity of the 653*33f37583SAndroid Build Coastguard Workerinstalled packages unnoticed. This is a regression for Android where all system 654*33f37583SAndroid Build Coastguard Workercomponents were stored in read-only file systems whose integrity is protected by 655*33f37583SAndroid Build Coastguard Workerdm-verity for every I/O. Any tampering to system components must be prohibited, 656*33f37583SAndroid Build Coastguard Workeror be detectable so that the device can refuse to boot if compromised. 657*33f37583SAndroid Build Coastguard Worker 658*33f37583SAndroid Build Coastguard Worker### dm-crypt for integrity 659*33f37583SAndroid Build Coastguard Worker 660*33f37583SAndroid Build Coastguard WorkerThe files in an APEX container are from built-in partitions (for example, the 661*33f37583SAndroid Build Coastguard Worker`/system` partition) that are protected by dm-verity, where any modification to 662*33f37583SAndroid Build Coastguard Workerthe files are prohibited even after the partitions are mounted. To provide the 663*33f37583SAndroid Build Coastguard Workersame level of security to the files, all files in an APEX are stored in a file 664*33f37583SAndroid Build Coastguard Workersystem image that is paired with a hash tree and a vbmeta descriptor. Without 665*33f37583SAndroid Build Coastguard Workerdm-verity, an APEX in the `/data` partition is vulnerable to unintended 666*33f37583SAndroid Build Coastguard Workermodifications made after it's verified and installed. 667*33f37583SAndroid Build Coastguard Worker 668*33f37583SAndroid Build Coastguard WorkerIn fact, the `/data` partition is also protected by encryption layers such as 669*33f37583SAndroid Build Coastguard Workerdm-crypt. Although this provides some level of protection against tampering, its 670*33f37583SAndroid Build Coastguard Workerprimary purpose is privacy, not integrity. When an attacker gains access to the 671*33f37583SAndroid Build Coastguard Worker`/data` partition, there can be no further protection, and this again is a 672*33f37583SAndroid Build Coastguard Workerregression compared to every system component being in the `/system` partition. 673*33f37583SAndroid Build Coastguard WorkerThe hash tree inside an APEX file together with dm-verity provides the same 674*33f37583SAndroid Build Coastguard Workerlevel of content protection. 675*33f37583SAndroid Build Coastguard Worker 676*33f37583SAndroid Build Coastguard Worker### Redirecting paths from `/system` to `/apex` 677*33f37583SAndroid Build Coastguard Worker 678*33f37583SAndroid Build Coastguard WorkerSystem component files packaged in an APEX are accessible via new paths like 679*33f37583SAndroid Build Coastguard Worker`/apex/<name>/lib/libfoo.so`. When the files were part of the `/system` 680*33f37583SAndroid Build Coastguard Workerpartition, they were accessible via paths such as `/system/lib/libfoo.so`. A 681*33f37583SAndroid Build Coastguard Workerclient of an APEX file (other APEX files or the platform) should use the new 682*33f37583SAndroid Build Coastguard Workerpaths. This change in paths might require updates to the existing code. 683*33f37583SAndroid Build Coastguard Worker 684*33f37583SAndroid Build Coastguard WorkerOne way to avoid the path change is to overlay the file contents in an APEX file 685*33f37583SAndroid Build Coastguard Workerover the `/system` partition. However, we decided not to overlay files over the 686*33f37583SAndroid Build Coastguard Worker`/system` partition because we believed this would negatively affect performance 687*33f37583SAndroid Build Coastguard Workeras the number of files being overlayed (possibly even stacked one after another) 688*33f37583SAndroid Build Coastguard Workerincreases. 689*33f37583SAndroid Build Coastguard Worker 690*33f37583SAndroid Build Coastguard WorkerAnother option was to hijack file access functions such as `open`, `stat`, and 691*33f37583SAndroid Build Coastguard Worker`readlink`, so that paths that start with `/system` are redirected to their 692*33f37583SAndroid Build Coastguard Workercorresponding paths under `/apex`. We discarded this option because it's 693*33f37583SAndroid Build Coastguard Workerpractically infeasible to change all functions that accept paths. For example, 694*33f37583SAndroid Build Coastguard Workersome apps statically link Bionic, which implements the functions. In that case, 695*33f37583SAndroid Build Coastguard Workerthe redirection won't happen for the app. 696