• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

README.mdD15-Dec-202426.8 KiB696527

apex-format.pngD14-Jan-202415.3 KiB

compressed-apex-format.pngD14-Jan-202426.1 KiB

howto.mdD15-Dec-202417.7 KiB525402

README.md

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