README.md
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![APEX file format](apex-format.png)
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