Merge "Keystore signing and verification test"
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 55d1eae..5aaf79f 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -23,7 +23,6 @@
"apex",
"linkerconfig",
"second_stage_resources",
- "postinstall",
]
microdroid_symlinks = [
diff --git a/microdroid/README.md b/microdroid/README.md
index 6d3491c..802e847 100644
--- a/microdroid/README.md
+++ b/microdroid/README.md
@@ -7,7 +7,7 @@
## Prerequisites
-Any 64-bit target (either x86_64 or arm64) is supported. 32-bit target is not
+Any 64-bit target (either x86\_64 or arm64) is supported. 32-bit target is not
supported. Note that we currently don't support user builds; only userdebug
builds are supported.
@@ -39,7 +39,7 @@
adb reboot
```
-If your target is x86_64 (e.g. `aosp_cf_x86_64_phone`), replace `aosp_arm64`
+If your target is x86\_64 (e.g. `aosp_cf_x86_64_phone`), replace `aosp_arm64`
with `aosp_x86_64`.
## Building an app
@@ -72,7 +72,7 @@
"os": {"name": "microdroid"},
"task": {
"type": "microdroid_launcher",
- "command": "MyMicrodroidApp.so",
+ "command": "MyMicrodroidApp.so"
},
"apexes": [
{"name": "com.android.adbd"},
@@ -107,9 +107,9 @@
Finally, you build and sign the APK.
```sh
-TARGET_BUILD_APPS=MyMicrodroidApp m dist
+TARGET_BUILD_APPS=MyApp m dist
m apksigner
-apksigner sign --ks path_to_keystore out/dist/MyMicrodroidApp.apk
+apksigner sign --ks path_to_keystore out/dist/MyApp.apk
```
`path_to_keystore` should be replaced with the actual path to the keystore,
@@ -127,7 +127,7 @@
First of all, install the signed APK to the target device.
```sh
-adb install out/dist/MyMicrodroidApp.apk
+adb install out/dist/MyApp.apk
```
### Creating `payload.img` manually (temporary step)
@@ -148,8 +148,9 @@
"com.android.sdkext"
],
"apk": {
- "name": "PACKAGE_NAME_OF_YOUR_APP"
+ "name": "PACKAGE_NAME_OF_YOUR_APP",
"path": "PATH_TO_YOUR_APP",
+ "idsig_path": "PATH_TO_APK_IDSIG"
}
}
```
@@ -169,12 +170,16 @@
It shall report a cryptic path similar to
`/data/app/~~OgZq==/com.acme.app-HudMahQ==/base.apk`.
+* `PATH_TO_APK_IDSIG`: path to the pushed APK idsig on the device. See below
+ `adb push` command: it will be `/data/local/tmp/virt/MyApp.apk.idsig` in this
+ example.
+
Once the file is done, execute the following command to push it to the device
and run `mk_payload` to create `payload.img`:
```sh
TEST_ROOT=/data/local/tmp/virt
-adb push out/dist/MyMicrodroidApp.apk.idsig $TEST_ROOT/MyMicrodroidApp.apk.idsig
+adb push out/dist/MyApp.apk.idsig $TEST_ROOT/MyApp.apk.idsig
adb push path_to_payload.json $TEST_ROOT/payload.json
adb shell /apex/com.android.virt/bin/my_payload $TEST_ROOT/payload.json $TEST_ROOT/payload.img
adb shell chmod go+r $TEST_ROOT/payload*
diff --git a/microdroid/sepolicy/system/private/file_contexts b/microdroid/sepolicy/system/private/file_contexts
index c4b4b2c..7e6048e 100644
--- a/microdroid/sepolicy/system/private/file_contexts
+++ b/microdroid/sepolicy/system/private/file_contexts
@@ -1,33 +1,19 @@
-# This is a copy of system/sepolicy/private/file_contexts to build microdroid.img.
-# TODO(inseob): Remove unnecessary entries after experiment
-
###########################################
# Root
/ u:object_r:rootfs:s0
# Data files
-/adb_keys u:object_r:adb_keys_file:s0
/build\.prop u:object_r:rootfs:s0
-/default\.prop u:object_r:rootfs:s0
-/fstab\..* u:object_r:rootfs:s0
/init\..* u:object_r:rootfs:s0
-/res(/.*)? u:object_r:rootfs:s0
-/selinux_version u:object_r:rootfs:s0
-/ueventd\..* u:object_r:rootfs:s0
-/verity_key u:object_r:rootfs:s0
# Executables
/init u:object_r:init_exec:s0
-/sbin(/.*)? u:object_r:rootfs:s0
# For kernel modules
/lib(/.*)? u:object_r:rootfs:s0
# Empty directories
/lost\+found u:object_r:rootfs:s0
-/acct u:object_r:cgroup:s0
-/config u:object_r:rootfs:s0
-/data_mirror u:object_r:mirror_data_file:s0
/debug_ramdisk u:object_r:tmpfs:s0
/mnt u:object_r:tmpfs:s0
/proc u:object_r:rootfs:s0
@@ -35,170 +21,69 @@
/sys u:object_r:sysfs:s0
/apex u:object_r:apex_mnt_dir:s0
-# Postinstall directories
-/postinstall u:object_r:postinstall_mnt_dir:s0
-/postinstall/apex u:object_r:postinstall_apex_mnt_dir:s0
-
/apex/(\.(bootstrap|default)-)?apex-info-list.xml u:object_r:apex_info_file:s0
# Symlinks
/bin u:object_r:rootfs:s0
-/bugreports u:object_r:rootfs:s0
-/charger u:object_r:rootfs:s0
/d u:object_r:rootfs:s0
/etc u:object_r:rootfs:s0
-/sdcard u:object_r:rootfs:s0
-
-# SELinux policy files
-/vendor_file_contexts u:object_r:file_contexts_file:s0
-/nonplat_file_contexts u:object_r:file_contexts_file:s0
-/plat_file_contexts u:object_r:file_contexts_file:s0
-/product_file_contexts u:object_r:file_contexts_file:s0
-/mapping_sepolicy\.cil u:object_r:sepolicy_file:s0
-/nonplat_sepolicy\.cil u:object_r:sepolicy_file:s0
-/plat_sepolicy\.cil u:object_r:sepolicy_file:s0
-/plat_property_contexts u:object_r:property_contexts_file:s0
-/product_property_contexts u:object_r:property_contexts_file:s0
-/nonplat_property_contexts u:object_r:property_contexts_file:s0
-/vendor_property_contexts u:object_r:property_contexts_file:s0
-/seapp_contexts u:object_r:seapp_contexts_file:s0
-/nonplat_seapp_contexts u:object_r:seapp_contexts_file:s0
-/vendor_seapp_contexts u:object_r:seapp_contexts_file:s0
-/plat_seapp_contexts u:object_r:seapp_contexts_file:s0
-/sepolicy u:object_r:sepolicy_file:s0
-/plat_service_contexts u:object_r:service_contexts_file:s0
-/plat_hwservice_contexts u:object_r:hwservice_contexts_file:s0
-/plat_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
-/nonplat_service_contexts u:object_r:nonplat_service_contexts_file:s0
-# Use nonplat_service_contexts_file to allow servicemanager to read it
-# on non full-treble devices.
-/vendor_service_contexts u:object_r:nonplat_service_contexts_file:s0
-/nonplat_hwservice_contexts u:object_r:hwservice_contexts_file:s0
-/vendor_hwservice_contexts u:object_r:hwservice_contexts_file:s0
-/vndservice_contexts u:object_r:vndservice_contexts_file:s0
##########################
# Devices
#
/dev(/.*)? u:object_r:device:s0
-/dev/adf[0-9]* u:object_r:graphics_device:s0
-/dev/adf-interface[0-9]*\.[0-9]* u:object_r:graphics_device:s0
-/dev/adf-overlay-engine[0-9]*\.[0-9]* u:object_r:graphics_device:s0
/dev/ashmem u:object_r:ashmem_device:s0
/dev/ashmem(.*)? u:object_r:ashmem_libcutils_device:s0
-/dev/audio.* u:object_r:audio_device:s0
/dev/binder u:object_r:binder_device:s0
/dev/block(/.*)? u:object_r:block_device:s0
/dev/block/dm-[0-9]+ u:object_r:dm_device:s0
/dev/block/loop[0-9]* u:object_r:loop_device:s0
/dev/block/vd[a-z][0-9]* u:object_r:vd_device:s0
-/dev/block/vold/.+ u:object_r:vold_device:s0
/dev/block/ram[0-9]* u:object_r:ram_device:s0
/dev/block/zram[0-9]* u:object_r:ram_device:s0
-/dev/boringssl/selftest(/.*)? u:object_r:boringssl_self_test_marker:s0
-/dev/bus/usb(.*)? u:object_r:usb_device:s0
/dev/console u:object_r:console_device:s0
-/dev/cpu_variant:.* u:object_r:dev_cpu_variant:s0
/dev/dma_heap(/.*)? u:object_r:dmabuf_heap_device:s0
/dev/dma_heap/system u:object_r:dmabuf_system_heap_device:s0
/dev/dma_heap/system-uncached u:object_r:dmabuf_system_heap_device:s0
/dev/dma_heap/system-secure(.*) u:object_r:dmabuf_system_secure_heap_device:s0
/dev/dm-user(/.*)? u:object_r:dm_user_device:s0
/dev/device-mapper u:object_r:dm_device:s0
-/dev/eac u:object_r:audio_device:s0
/dev/event-log-tags u:object_r:runtime_event_log_tags_file:s0
/dev/cgroup_info(/.*)? u:object_r:cgroup_rc_file:s0
-/dev/fscklogs(/.*)? u:object_r:fscklogs:s0
/dev/fuse u:object_r:fuse_device:s0
-/dev/gnss[0-9]+ u:object_r:gnss_device:s0
-/dev/graphics(/.*)? u:object_r:graphics_device:s0
/dev/hw_random u:object_r:hw_random_device:s0
/dev/hwbinder u:object_r:hwbinder_device:s0
-/dev/input(/.*)? u:object_r:input_device:s0
-/dev/iio:device[0-9]+ u:object_r:iio_device:s0
-/dev/ion u:object_r:ion_device:s0
-/dev/keychord u:object_r:keychord_device:s0
/dev/loop-control u:object_r:loop_control_device:s0
-/dev/modem.* u:object_r:radio_device:s0
-/dev/mtp_usb u:object_r:mtp_device:s0
-/dev/pmsg0 u:object_r:pmsg_device:s0
-/dev/pn544 u:object_r:nfc_device:s0
-/dev/port u:object_r:port_device:s0
/dev/ppp u:object_r:ppp_device:s0
/dev/ptmx u:object_r:ptmx_device:s0
-/dev/pvrsrvkm u:object_r:gpu_device:s0
/dev/kmsg u:object_r:kmsg_device:s0
/dev/kmsg_debug u:object_r:kmsg_debug_device:s0
/dev/kvm u:object_r:kvm_device:s0
/dev/null u:object_r:null_device:s0
-/dev/nvhdcp1 u:object_r:video_device:s0
/dev/random u:object_r:random_device:s0
-/dev/rpmsg-omx[0-9] u:object_r:rpmsg_device:s0
-/dev/rproc_user u:object_r:rpmsg_device:s0
/dev/rtc[0-9] u:object_r:rtc_device:s0
-/dev/snd(/.*)? u:object_r:audio_device:s0
/dev/socket(/.*)? u:object_r:socket_device:s0
/dev/socket/adbd u:object_r:adbd_socket:s0
-/dev/socket/dnsproxyd u:object_r:dnsproxyd_socket:s0
/dev/socket/dumpstate u:object_r:dumpstate_socket:s0
-/dev/socket/fwmarkd u:object_r:fwmarkd_socket:s0
-/dev/socket/lmkd u:object_r:lmkd_socket:s0
/dev/socket/logd u:object_r:logd_socket:s0
/dev/socket/logdr u:object_r:logdr_socket:s0
/dev/socket/logdw u:object_r:logdw_socket:s0
-/dev/socket/statsdw u:object_r:statsdw_socket:s0
-/dev/socket/mdns u:object_r:mdns_socket:s0
-/dev/socket/mdnsd u:object_r:mdnsd_socket:s0
-/dev/socket/mtpd u:object_r:mtpd_socket:s0
-/dev/socket/pdx/system/buffer_hub u:object_r:pdx_bufferhub_dir:s0
-/dev/socket/pdx/system/buffer_hub/client u:object_r:pdx_bufferhub_client_endpoint_socket:s0
-/dev/socket/pdx/system/performance u:object_r:pdx_performance_dir:s0
-/dev/socket/pdx/system/performance/client u:object_r:pdx_performance_client_endpoint_socket:s0
-/dev/socket/pdx/system/vr/display u:object_r:pdx_display_dir:s0
-/dev/socket/pdx/system/vr/display/client u:object_r:pdx_display_client_endpoint_socket:s0
-/dev/socket/pdx/system/vr/display/manager u:object_r:pdx_display_manager_endpoint_socket:s0
-/dev/socket/pdx/system/vr/display/screenshot u:object_r:pdx_display_screenshot_endpoint_socket:s0
-/dev/socket/pdx/system/vr/display/vsync u:object_r:pdx_display_vsync_endpoint_socket:s0
/dev/socket/property_service u:object_r:property_socket:s0
-/dev/socket/racoon u:object_r:racoon_socket:s0
-/dev/socket/recovery u:object_r:recovery_socket:s0
-/dev/socket/rild u:object_r:rild_socket:s0
-/dev/socket/rild-debug u:object_r:rild_debug_socket:s0
-/dev/socket/snapuserd u:object_r:snapuserd_socket:s0
/dev/socket/tombstoned_crash u:object_r:tombstoned_crash_socket:s0
/dev/socket/tombstoned_java_trace u:object_r:tombstoned_java_trace_socket:s0
/dev/socket/tombstoned_intercept u:object_r:tombstoned_intercept_socket:s0
-/dev/socket/traced_consumer u:object_r:traced_consumer_socket:s0
-/dev/socket/traced_perf u:object_r:traced_perf_socket:s0
-/dev/socket/traced_producer u:object_r:traced_producer_socket:s0
-/dev/socket/heapprofd u:object_r:heapprofd_socket:s0
-/dev/socket/uncrypt u:object_r:uncrypt_socket:s0
-/dev/socket/wpa_eth[0-9] u:object_r:wpa_socket:s0
-/dev/socket/wpa_wlan[0-9] u:object_r:wpa_socket:s0
-/dev/socket/zygote u:object_r:zygote_socket:s0
-/dev/socket/zygote_secondary u:object_r:zygote_socket:s0
-/dev/socket/usap_pool_primary u:object_r:zygote_socket:s0
-/dev/socket/usap_pool_secondary u:object_r:zygote_socket:s0
-/dev/spdif_out.* u:object_r:audio_device:s0
/dev/sys/block/by-name/userdata(/.*)? u:object_r:userdata_sysdev:s0
/dev/sys/fs/by-name/userdata(/.*)? u:object_r:userdata_sysdev:s0
/dev/tty u:object_r:owntty_device:s0
/dev/tty[0-9]* u:object_r:tty_device:s0
/dev/ttyS[0-9]* u:object_r:serial_device:s0
-/dev/ttyUSB[0-9]* u:object_r:usb_serial_device:s0
-/dev/ttyACM[0-9]* u:object_r:usb_serial_device:s0
/dev/tun u:object_r:tun_device:s0
/dev/uhid u:object_r:uhid_device:s0
/dev/uinput u:object_r:uhid_device:s0
/dev/uio[0-9]* u:object_r:uio_device:s0
/dev/urandom u:object_r:random_device:s0
-/dev/usb_accessory u:object_r:usbaccessory_device:s0
-/dev/v4l-touch[0-9]* u:object_r:input_device:s0
/dev/vhost-vsock u:object_r:kvm_device:s0
-/dev/video[0-9]* u:object_r:video_device:s0
/dev/vndbinder u:object_r:vndbinder_device:s0
-/dev/watchdog u:object_r:watchdog_device:s0
-/dev/xt_qtaguid u:object_r:qtaguid_device:s0
/dev/zero u:object_r:zero_device:s0
/dev/__properties__ u:object_r:properties_device:s0
/dev/__properties__/property_info u:object_r:property_info:s0
@@ -209,134 +94,29 @@
#############################
# System files
#
-/system(/.*)? u:object_r:system_file:s0
-/system/apex/com.android.art u:object_r:art_apex_dir:s0
-/system/lib(64)?(/.*)? u:object_r:system_lib_file:s0
+/system(/.*)? u:object_r:system_file:s0
+/system/lib(64)?(/.*)? u:object_r:system_lib_file:s0
/system/lib(64)?/bootstrap(/.*)? u:object_r:system_bootstrap_lib_file:s0
-/system/bin/mm_events u:object_r:mm_events_exec:s0
-/system/bin/atrace u:object_r:atrace_exec:s0
-/system/bin/auditctl u:object_r:auditctl_exec:s0
-/system/bin/bcc u:object_r:rs_exec:s0
-/system/bin/blank_screen u:object_r:blank_screen_exec:s0
-/system/bin/boringssl_self_test(32|64) u:object_r:boringssl_self_test_exec:s0
-/system/bin/charger u:object_r:charger_exec:s0
-/system/bin/canhalconfigurator u:object_r:canhalconfigurator_exec:s0
-/system/bin/e2fsdroid u:object_r:e2fs_exec:s0
-/system/bin/mke2fs u:object_r:e2fs_exec:s0
-/system/bin/e2fsck -- u:object_r:fsck_exec:s0
-/system/bin/fsck\.exfat -- u:object_r:fsck_exec:s0
-/system/bin/fsck\.f2fs -- u:object_r:fsck_exec:s0
-/system/bin/init u:object_r:init_exec:s0
-# TODO(/123600489): merge mini-keyctl into toybox
-/system/bin/mini-keyctl -- u:object_r:toolbox_exec:s0
-/system/bin/fsverity_init u:object_r:fsverity_init_exec:s0
-/system/bin/sload_f2fs -- u:object_r:e2fs_exec:s0
-/system/bin/make_f2fs -- u:object_r:e2fs_exec:s0
-/system/bin/fsck_msdos -- u:object_r:fsck_exec:s0
-/system/bin/tcpdump -- u:object_r:tcpdump_exec:s0
-/system/bin/tune2fs -- u:object_r:fsck_exec:s0
-/system/bin/resize2fs -- u:object_r:fsck_exec:s0
-/system/bin/toolbox -- u:object_r:toolbox_exec:s0
-/system/bin/toybox -- u:object_r:toolbox_exec:s0
-/system/bin/ld\.mc u:object_r:rs_exec:s0
-/system/bin/logcat -- u:object_r:logcat_exec:s0
-/system/bin/logcatd -- u:object_r:logcat_exec:s0
-/system/bin/sh -- u:object_r:shell_exec:s0
-/system/bin/run-as -- u:object_r:runas_exec:s0
-/system/bin/bootanimation u:object_r:bootanim_exec:s0
-/system/bin/bootstat u:object_r:bootstat_exec:s0
-/system/bin/app_process32 u:object_r:zygote_exec:s0
-/system/bin/app_process64 u:object_r:zygote_exec:s0
-/system/bin/servicemanager u:object_r:servicemanager_exec:s0
-/system/bin/hwservicemanager u:object_r:hwservicemanager_exec:s0
-/system/bin/surfaceflinger u:object_r:surfaceflinger_exec:s0
-/system/bin/gpuservice u:object_r:gpuservice_exec:s0
-/system/bin/bufferhubd u:object_r:bufferhubd_exec:s0
-/system/bin/performanced u:object_r:performanced_exec:s0
-/system/bin/drmserver u:object_r:drmserver_exec:s0
-/system/bin/dumpstate u:object_r:dumpstate_exec:s0
-/system/bin/incident u:object_r:incident_exec:s0
-/system/bin/incidentd u:object_r:incidentd_exec:s0
-/system/bin/incident_helper u:object_r:incident_helper_exec:s0
-/system/bin/iw u:object_r:iw_exec:s0
-/system/bin/netutils-wrapper-1\.0 u:object_r:netutils_wrapper_exec:s0
-/system/bin/vold u:object_r:vold_exec:s0
-/system/bin/netd u:object_r:netd_exec:s0
-/system/bin/wificond u:object_r:wificond_exec:s0
-/system/bin/audioserver u:object_r:audioserver_exec:s0
-/system/bin/mediadrmserver u:object_r:mediadrmserver_exec:s0
-/system/bin/mediaserver u:object_r:mediaserver_exec:s0
-/system/bin/mediametrics u:object_r:mediametrics_exec:s0
-/system/bin/cameraserver u:object_r:cameraserver_exec:s0
-/system/bin/mediaextractor u:object_r:mediaextractor_exec:s0
-/system/bin/mediaswcodec u:object_r:mediaswcodec_exec:s0
-/system/bin/mediatranscoding u:object_r:mediatranscoding_exec:s0
-/system/bin/mediatuner u:object_r:mediatuner_exec:s0
-/system/bin/mdnsd u:object_r:mdnsd_exec:s0
-/system/bin/installd u:object_r:installd_exec:s0
-/system/bin/otapreopt_chroot u:object_r:otapreopt_chroot_exec:s0
-/system/bin/otapreopt_slot u:object_r:otapreopt_slot_exec:s0
-/system/bin/credstore u:object_r:credstore_exec:s0
-/system/bin/keystore u:object_r:keystore_exec:s0
-/system/bin/keystore2 u:object_r:keystore_exec:s0
-/system/bin/fingerprintd u:object_r:fingerprintd_exec:s0
-/system/bin/gatekeeperd u:object_r:gatekeeperd_exec:s0
-/system/bin/tombstoned u:object_r:tombstoned_exec:s0
-/system/bin/recovery-persist u:object_r:recovery_persist_exec:s0
-/system/bin/recovery-refresh u:object_r:recovery_refresh_exec:s0
-/system/bin/sdcard u:object_r:sdcardd_exec:s0
-/system/bin/snapshotctl u:object_r:snapshotctl_exec:s0
-/system/bin/dhcpcd u:object_r:dhcp_exec:s0
-/system/bin/dhcpcd-6\.8\.2 u:object_r:dhcp_exec:s0
-/system/bin/mtpd u:object_r:mtp_exec:s0
-/system/bin/pppd u:object_r:ppp_exec:s0
-/system/bin/racoon u:object_r:racoon_exec:s0
-/system/xbin/su u:object_r:su_exec:s0
-/system/bin/dnsmasq u:object_r:dnsmasq_exec:s0
-/system/bin/healthd u:object_r:healthd_exec:s0
-/system/bin/clatd u:object_r:clatd_exec:s0
+/system/bin/apexd u:object_r:apexd_exec:s0
/system/bin/linker(64)? u:object_r:system_linker_exec:s0
/system/bin/linkerconfig u:object_r:linkerconfig_exec:s0
/system/bin/bootstrap/linker(64)? u:object_r:system_linker_exec:s0
/system/bin/bootstrap/linkerconfig u:object_r:linkerconfig_exec:s0
-/system/bin/llkd u:object_r:llkd_exec:s0
-/system/bin/lmkd u:object_r:lmkd_exec:s0
-/system/bin/usbd u:object_r:usbd_exec:s0
-/system/bin/inputflinger u:object_r:inputflinger_exec:s0
+/system/bin/servicemanager u:object_r:servicemanager_exec:s0
+/system/bin/hwservicemanager u:object_r:hwservicemanager_exec:s0
+/system/bin/init u:object_r:init_exec:s0
+/system/bin/keystore2 u:object_r:keystore_exec:s0
+/system/bin/logcat -- u:object_r:logcat_exec:s0
/system/bin/logd u:object_r:logd_exec:s0
-/system/bin/lpdumpd u:object_r:lpdumpd_exec:s0
-/system/bin/rss_hwm_reset u:object_r:rss_hwm_reset_exec:s0
-/system/bin/perfetto u:object_r:perfetto_exec:s0
-/system/bin/traced u:object_r:traced_exec:s0
-/system/bin/traced_perf u:object_r:traced_perf_exec:s0
-/system/bin/traced_probes u:object_r:traced_probes_exec:s0
-/system/bin/heapprofd u:object_r:heapprofd_exec:s0
-/system/bin/uncrypt u:object_r:uncrypt_exec:s0
-/system/bin/update_verifier u:object_r:update_verifier_exec:s0
-/system/bin/logwrapper u:object_r:system_file:s0
-/system/bin/vdc u:object_r:vdc_exec:s0
-/system/bin/cppreopts\.sh u:object_r:cppreopts_exec:s0
-/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
-/system/bin/preopt2cachename u:object_r:preopt2cachename_exec:s0
-/system/bin/viewcompiler u:object_r:viewcompiler_exec:s0
-/system/bin/iorapd u:object_r:iorapd_exec:s0
-/system/bin/iorap\.inode2filename u:object_r:iorap_inode2filename_exec:s0
-/system/bin/iorap\.prefetcherd u:object_r:iorap_prefetcherd_exec:s0
-/system/bin/sgdisk u:object_r:sgdisk_exec:s0
-/system/bin/blkid u:object_r:blkid_exec:s0
-/system/bin/tzdatacheck u:object_r:tzdatacheck_exec:s0
-/system/bin/flags_health_check -- u:object_r:flags_health_check_exec:s0
-/system/bin/idmap u:object_r:idmap_exec:s0
-/system/bin/idmap2(d)? u:object_r:idmap_exec:s0
-/system/bin/update_engine u:object_r:update_engine_exec:s0
-/system/bin/profcollectd u:object_r:profcollectd_exec:s0
-/system/bin/profcollectctl u:object_r:profcollectd_exec:s0
-/system/bin/storaged u:object_r:storaged_exec:s0
-/system/bin/wpantund u:object_r:wpantund_exec:s0
-/system/bin/virtual_touchpad u:object_r:virtual_touchpad_exec:s0
-/system/bin/hw/android\.frameworks\.bufferhub@1\.0-service u:object_r:fwk_bufferhub_exec:s0
-/system/bin/hw/android\.hidl\.allocator@1\.0-service u:object_r:hal_allocator_default_exec:s0
-/system/bin/hw/android\.system\.suspend@1\.0-service u:object_r:system_suspend_exec:s0
+/system/bin/run-as -- u:object_r:runas_exec:s0
+/system/bin/sh -- u:object_r:shell_exec:s0
+/system/bin/tombstoned u:object_r:tombstoned_exec:s0
+/system/bin/toolbox -- u:object_r:toolbox_exec:s0
+/system/bin/toybox -- u:object_r:toolbox_exec:s0
+/system/bin/zipfuse u:object_r:zipfuse_exec:s0
+/system/bin/microdroid_launcher u:object_r:microdroid_launcher_exec:s0
+/system/bin/microdroid_manager u:object_r:microdroid_manager_exec:s0
+/system/bin/apkdmverity u:object_r:apkdmverity_exec:s0
/system/etc/cgroups\.json u:object_r:cgroup_desc_file:s0
/system/etc/task_profiles/cgroups_[0-9]+\.json u:object_r:cgroup_desc_api_file:s0
/system/etc/event-log-tags u:object_r:system_event_log_tags_file:s0
@@ -357,154 +137,13 @@
/system/etc/selinux/plat_and_mapping_sepolicy\.cil\.sha256 u:object_r:sepolicy_file:s0
/system/etc/task_profiles\.json u:object_r:task_profiles_file:s0
/system/etc/task_profiles/task_profiles_[0-9]+\.json u:object_r:task_profiles_api_file:s0
-/system/usr/share/zoneinfo(/.*)? u:object_r:system_zoneinfo_file:s0
-/system/bin/vr_hwc u:object_r:vr_hwc_exec:s0
-/system/bin/adbd u:object_r:adbd_exec:s0
-/system/bin/vold_prepare_subdirs u:object_r:vold_prepare_subdirs_exec:s0
-/system/bin/stats u:object_r:stats_exec:s0
-/system/bin/statsd u:object_r:statsd_exec:s0
-/system/bin/bpfloader u:object_r:bpfloader_exec:s0
-/system/bin/watchdogd u:object_r:watchdogd_exec:s0
-/system/bin/apexd u:object_r:apexd_exec:s0
-/system/bin/gsid u:object_r:gsid_exec:s0
-/system/bin/simpleperf u:object_r:simpleperf_exec:s0
-/system/bin/simpleperf_app_runner u:object_r:simpleperf_app_runner_exec:s0
-/system/bin/migrate_legacy_obb_data\.sh u:object_r:migrate_legacy_obb_data_exec:s0
-/system/bin/android\.frameworks\.automotive\.display@1\.0-service u:object_r:automotive_display_service_exec:s0
-/system/bin/snapuserd u:object_r:snapuserd_exec:s0
-/system/bin/odsign u:object_r:odsign_exec:s0
-/system/bin/zipfuse u:object_r:zipfuse_exec:s0
-/system/bin/microdroid_launcher u:object_r:microdroid_launcher_exec:s0
-/system/bin/microdroid_manager u:object_r:microdroid_manager_exec:s0
-/system/bin/apkdmverity u:object_r:apkdmverity_exec:s0
#############################
# Vendor files
#
-/(vendor|system/vendor)(/.*)? u:object_r:vendor_file:s0
-/(vendor|system/vendor)/bin/sh u:object_r:vendor_shell_exec:s0
-/(vendor|system/vendor)/bin/toybox_vendor u:object_r:vendor_toolbox_exec:s0
-/(vendor|system/vendor)/bin/toolbox u:object_r:vendor_toolbox_exec:s0
-/(vendor|system/vendor)/etc(/.*)? u:object_r:vendor_configs_file:s0
-/(vendor|system/vendor)/etc/cgroups\.json u:object_r:vendor_cgroup_desc_file:s0
-/(vendor|system/vendor)/etc/task_profiles\.json u:object_r:vendor_task_profiles_file:s0
-
-/(vendor|system/vendor)/lib(64)?/egl(/.*)? u:object_r:same_process_hal_file:s0
-
-/(vendor|system/vendor)/lib(64)?/vndk-sp(/.*)? u:object_r:vndk_sp_file:s0
-
-/(vendor|system/vendor)/manifest\.xml u:object_r:vendor_configs_file:s0
-/(vendor|system/vendor)/compatibility_matrix\.xml u:object_r:vendor_configs_file:s0
-/(vendor|system/vendor)/etc/vintf(/.*)? u:object_r:vendor_configs_file:s0
-/(vendor|system/vendor)/app(/.*)? u:object_r:vendor_app_file:s0
-/(vendor|system/vendor)/priv-app(/.*)? u:object_r:vendor_app_file:s0
-/(vendor|system/vendor)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
-/(vendor|system/vendor)/framework(/.*)? u:object_r:vendor_framework_file:s0
-
-/(vendor|system/vendor)/apex(/[^/]+){0,2} u:object_r:vendor_apex_file:s0
-/(vendor|system/vendor)/bin/misc_writer u:object_r:vendor_misc_writer_exec:s0
-/(vendor|system/vendor)/bin/boringssl_self_test(32|64) u:object_r:vendor_boringssl_self_test_exec:s0
-
-# HAL location
-/(vendor|system/vendor)/lib(64)?/hw u:object_r:vendor_hal_file:s0
-
-/(vendor|system/vendor)/etc/selinux/nonplat_service_contexts u:object_r:nonplat_service_contexts_file:s0
-
-/(vendor|system/vendor)/etc/selinux/vendor_service_contexts u:object_r:vendor_service_contexts_file:s0
-
-#############################
-# OEM and ODM files
-#
-/(odm|vendor/odm)(/.*)? u:object_r:vendor_file:s0
-/(odm|vendor/odm)/lib(64)?/egl(/.*)? u:object_r:same_process_hal_file:s0
-/(odm|vendor/odm)/lib(64)?/hw u:object_r:vendor_hal_file:s0
-/(odm|vendor/odm)/lib(64)?/vndk-sp(/.*)? u:object_r:vndk_sp_file:s0
-/(odm|vendor/odm)/bin/sh u:object_r:vendor_shell_exec:s0
-/(odm|vendor/odm)/etc(/.*)? u:object_r:vendor_configs_file:s0
-/(odm|vendor/odm)/app(/.*)? u:object_r:vendor_app_file:s0
-/(odm|vendor/odm)/priv-app(/.*)? u:object_r:vendor_app_file:s0
-/(odm|vendor/odm)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
-/(odm|vendor/odm)/framework(/.*)? u:object_r:vendor_framework_file:s0
-
-# Input configuration
-/(odm|vendor/odm|vendor|system/vendor)/usr/keylayout(/.*)?\.kl u:object_r:vendor_keylayout_file:s0
-/(odm|vendor/odm|vendor|system/vendor)/usr/keychars(/.*)?\.kcm u:object_r:vendor_keychars_file:s0
-/(odm|vendor/odm|vendor|system/vendor)/usr/idc(/.*)?\.idc u:object_r:vendor_idc_file:s0
-
-/oem(/.*)? u:object_r:oemfs:s0
-/oem/overlay(/.*)? u:object_r:vendor_overlay_file:s0
-
-# The precompiled monolithic sepolicy will be under /odm only when
-# BOARD_USES_ODMIMAGE is true: a separate odm.img is built.
-/odm/etc/selinux/precompiled_sepolicy u:object_r:sepolicy_file:s0
-/odm/etc/selinux/precompiled_sepolicy\.plat_and_mapping\.sha256 u:object_r:sepolicy_file:s0
-
-/(odm|vendor/odm)/etc/selinux/odm_sepolicy\.cil u:object_r:sepolicy_file:s0
-/(odm|vendor/odm)/etc/selinux/odm_file_contexts u:object_r:file_contexts_file:s0
-/(odm|vendor/odm)/etc/selinux/odm_seapp_contexts u:object_r:seapp_contexts_file:s0
-/(odm|vendor/odm)/etc/selinux/odm_property_contexts u:object_r:property_contexts_file:s0
-/(odm|vendor/odm)/etc/selinux/odm_hwservice_contexts u:object_r:hwservice_contexts_file:s0
-/(odm|vendor/odm)/etc/selinux/odm_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
-/(odm|vendor/odm)/etc/selinux/odm_mac_permissions\.xml u:object_r:mac_perms_file:s0
-
-#############################
-# Product files
-#
-/(product|system/product)(/.*)? u:object_r:system_file:s0
-/(product|system/product)/etc/group u:object_r:system_group_file:s0
-/(product|system/product)/etc/passwd u:object_r:system_passwd_file:s0
-/(product|system/product)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
-
-/(product|system/product)/etc/selinux/product_file_contexts u:object_r:file_contexts_file:s0
-/(product|system/product)/etc/selinux/product_hwservice_contexts u:object_r:hwservice_contexts_file:s0
-/(product|system/product)/etc/selinux/product_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
-/(product|system/product)/etc/selinux/product_property_contexts u:object_r:property_contexts_file:s0
-/(product|system/product)/etc/selinux/product_seapp_contexts u:object_r:seapp_contexts_file:s0
-/(product|system/product)/etc/selinux/product_service_contexts u:object_r:service_contexts_file:s0
-/(product|system/product)/etc/selinux/product_mac_permissions\.xml u:object_r:mac_perms_file:s0
-
-/(product|system/product)/lib(64)?(/.*)? u:object_r:system_lib_file:s0
-
-#############################
-# SystemExt files
-#
-/(system_ext|system/system_ext)(/.*)? u:object_r:system_file:s0
-/(system_ext|system/system_ext)/etc/group u:object_r:system_group_file:s0
-/(system_ext|system/system_ext)/etc/passwd u:object_r:system_passwd_file:s0
-/(system_ext|system/system_ext)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
-
-/(system_ext|system/system_ext)/etc/selinux/system_ext_file_contexts u:object_r:file_contexts_file:s0
-/(system_ext|system/system_ext)/etc/selinux/system_ext_hwservice_contexts u:object_r:hwservice_contexts_file:s0
-/(system_ext|system/system_ext)/etc/selinux/system_ext_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
-/(system_ext|system/system_ext)/etc/selinux/system_ext_property_contexts u:object_r:property_contexts_file:s0
-/(system_ext|system/system_ext)/etc/selinux/system_ext_seapp_contexts u:object_r:seapp_contexts_file:s0
-/(system_ext|system/system_ext)/etc/selinux/system_ext_service_contexts u:object_r:service_contexts_file:s0
-/(system_ext|system/system_ext)/etc/selinux/system_ext_mac_permissions\.xml u:object_r:mac_perms_file:s0
-
-/(system_ext|system/system_ext)/bin/aidl_lazy_test_server u:object_r:aidl_lazy_test_server_exec:s0
-/(system_ext|system/system_ext)/bin/hidl_lazy_test_server u:object_r:hidl_lazy_test_server_exec:s0
-
-/(system_ext|system/system_ext)/lib(64)?(/.*)? u:object_r:system_lib_file:s0
-
-#############################
-# VendorDlkm files
-# This includes VENDOR Dynamically Loadable Kernel Modules and other misc files.
-#
-/(vendor_dlkm|vendor/vendor_dlkm|system/vendor/vendor_dlkm)(/.*)? u:object_r:vendor_file:s0
-
-#############################
-# OdmDlkm files
-# This includes ODM Dynamically Loadable Kernel Modules and other misc files.
-#
-/(odm_dlkm|vendor/odm_dlkm|system/vendor/odm_dlkm)(/.*)? u:object_r:vendor_file:s0
-
-#############################
-# Vendor files from /(product|system/product)/vendor_overlay
-#
-# NOTE: For additional vendor file contexts for vendor overlay files,
-# use device specific file_contexts.
-#
-/(product|system/product)/vendor_overlay/[0-9]+/.* u:object_r:vendor_file:s0
+/vendor(/.*)? u:object_r:vendor_file:s0
+/vendor/etc(/.*)? u:object_r:vendor_configs_file:s0
+/vendor/etc/vintf(/.*)? u:object_r:vendor_configs_file:s0
#############################
# Data files
@@ -514,305 +153,11 @@
#
/data u:object_r:system_data_root_file:s0
/data/(.*)? u:object_r:system_data_file:s0
-/data/system/environ(/.*)? u:object_r:environ_system_data_file:s0
-/data/system/packages\.list u:object_r:packages_list_file:s0
-/data/unencrypted(/.*)? u:object_r:unencrypted_data_file:s0
-/data/backup(/.*)? u:object_r:backup_data_file:s0
-/data/secure/backup(/.*)? u:object_r:backup_data_file:s0
-/data/system/ndebugsocket u:object_r:system_ndebug_socket:s0
-/data/system/unsolzygotesocket u:object_r:system_unsolzygote_socket:s0
-/data/drm(/.*)? u:object_r:drm_data_file:s0
-/data/resource-cache(/.*)? u:object_r:resourcecache_data_file:s0
-/data/dalvik-cache(/.*)? u:object_r:dalvikcache_data_file:s0
-/data/ota(/.*)? u:object_r:ota_data_file:s0
-/data/ota_package(/.*)? u:object_r:ota_package_file:s0
-/data/adb(/.*)? u:object_r:adb_data_file:s0
/data/anr(/.*)? u:object_r:anr_data_file:s0
-/data/apex(/.*)? u:object_r:apex_data_file:s0
-/data/apex/active/(.*)? u:object_r:staging_data_file:s0
-/data/apex/backup/(.*)? u:object_r:staging_data_file:s0
-/data/apex/decompressed/(.*)? u:object_r:staging_data_file:s0
-/data/apex/ota_reserved(/.*)? u:object_r:apex_ota_reserved_file:s0
-/data/app(/.*)? u:object_r:apk_data_file:s0
-# Traditional /data/app/[packageName]-[randomString]/base.apk location
-/data/app/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
-# /data/app/[randomStringA]/[packageName]-[randomStringB]/base.apk layout
-/data/app/[^/]+/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
-/data/app/vmdl[^/]+\.tmp(/.*)? u:object_r:apk_tmp_file:s0
-/data/app/vmdl[^/]+\.tmp/oat(/.*)? u:object_r:dalvikcache_data_file:s0
-/data/app-private(/.*)? u:object_r:apk_private_data_file:s0
-/data/app-private/vmdl.*\.tmp(/.*)? u:object_r:apk_private_tmp_file:s0
-/data/gsi(/.*)? u:object_r:gsi_data_file:s0
-/data/gsi_persistent_data u:object_r:gsi_persistent_data_file:s0
-/data/gsi/ota(/.*)? u:object_r:ota_image_data_file:s0
-/data/tombstones(/.*)? u:object_r:tombstone_data_file:s0
-/data/vendor/tombstones/wifi(/.*)? u:object_r:tombstone_wifi_data_file:s0
/data/local/tests(/.*)? u:object_r:shell_test_data_file:s0
/data/local/tmp(/.*)? u:object_r:shell_data_file:s0
/data/local/tmp/ltp(/.*)? u:object_r:nativetest_data_file:s0
/data/local/traces(/.*)? u:object_r:trace_data_file:s0
-/data/media(/.*)? u:object_r:media_rw_data_file:s0
-/data/mediadrm(/.*)? u:object_r:media_data_file:s0
-/data/nativetest(/.*)? u:object_r:nativetest_data_file:s0
-/data/nativetest64(/.*)? u:object_r:nativetest_data_file:s0
-# This directory was removed after Q Beta 2, but we need to preserve labels for upgrading devices.
-/data/pkg_staging(/.*)? u:object_r:staging_data_file:s0
-/data/property(/.*)? u:object_r:property_data_file:s0
-/data/preloads(/.*)? u:object_r:preloads_data_file:s0
-/data/preloads/media(/.*)? u:object_r:preloads_media_file:s0
-/data/preloads/demo(/.*)? u:object_r:preloads_media_file:s0
-/data/server_configurable_flags(/.*)? u:object_r:server_configurable_flags_data_file:s0
-/data/app-staging(/.*)? u:object_r:staging_data_file:s0
-# Ensure we have the same labels as /data/app or /data/apex/active
-# to avoid restorecon conflicts
-/data/rollback/\d+/[^/]+/.*\.apk u:object_r:apk_data_file:s0
-/data/rollback/\d+/[^/]+/.*\.apex u:object_r:staging_data_file:s0
-/data/fonts/files(/.*)? u:object_r:font_data_file:s0
-
-# Misc data
-/data/misc/adb(/.*)? u:object_r:adb_keys_file:s0
-/data/misc/a11ytrace(/.*)? u:object_r:accessibility_trace_data_file:s0
-/data/misc/apexdata(/.*)? u:object_r:apex_module_data_file:s0
-/data/misc/apexdata/com\.android\.art(/.*)? u:object_r:apex_art_data_file:s0
-/data/misc/apexdata/com\.android\.permission(/.*)? u:object_r:apex_permission_data_file:s0
-/data/misc/apexdata/com\.android\.scheduling(/.*)? u:object_r:apex_scheduling_data_file:s0
-/data/misc/apexdata/com\.android\.wifi(/.*)? u:object_r:apex_wifi_data_file:s0
-/data/misc/apexrollback(/.*)? u:object_r:apex_rollback_data_file:s0
-/data/misc/apns(/.*)? u:object_r:radio_data_file:s0
-/data/misc/appcompat(/.*)? u:object_r:appcompat_data_file:s0
-/data/misc/audio(/.*)? u:object_r:audio_data_file:s0
-/data/misc/audioserver(/.*)? u:object_r:audioserver_data_file:s0
-/data/misc/audiohal(/.*)? u:object_r:audiohal_data_file:s0
-/data/misc/bootstat(/.*)? u:object_r:bootstat_data_file:s0
-/data/misc/boottrace(/.*)? u:object_r:boottrace_data_file:s0
-/data/misc/bluetooth(/.*)? u:object_r:bluetooth_data_file:s0
-/data/misc/bluetooth/logs(/.*)? u:object_r:bluetooth_logs_data_file:s0
-/data/misc/bluedroid(/.*)? u:object_r:bluetooth_data_file:s0
-/data/misc/bluedroid/\.a2dp_ctrl u:object_r:bluetooth_socket:s0
-/data/misc/bluedroid/\.a2dp_data u:object_r:bluetooth_socket:s0
-/data/misc/camera(/.*)? u:object_r:camera_data_file:s0
-/data/misc/carrierid(/.*)? u:object_r:radio_data_file:s0
-/data/misc/dhcp(/.*)? u:object_r:dhcp_data_file:s0
-/data/misc/dhcp-6\.8\.2(/.*)? u:object_r:dhcp_data_file:s0
-/data/misc/emergencynumberdb(/.*)? u:object_r:emergency_data_file:s0
-/data/misc/gatekeeper(/.*)? u:object_r:gatekeeper_data_file:s0
-/data/misc/incidents(/.*)? u:object_r:incident_data_file:s0
-/data/misc/installd(/.*)? u:object_r:install_data_file:s0
-/data/misc/keychain(/.*)? u:object_r:keychain_data_file:s0
-/data/misc/credstore(/.*)? u:object_r:credstore_data_file:s0
/data/misc/keystore(/.*)? u:object_r:keystore_data_file:s0
-/data/misc/logd(/.*)? u:object_r:misc_logd_file:s0
-/data/misc/media(/.*)? u:object_r:media_data_file:s0
-/data/misc/net(/.*)? u:object_r:net_data_file:s0
-/data/misc/network_watchlist(/.*)? u:object_r:network_watchlist_data_file:s0
-/data/misc/nfc/logs(/.*)? u:object_r:nfc_logs_data_file:s0
-/data/misc/odrefresh(/.*)? u:object_r:odrefresh_data_file:s0
-/data/misc/odsign(/.*)? u:object_r:odsign_data_file:s0
-/data/misc/perfetto-traces/bugreport(.*)? u:object_r:perfetto_traces_bugreport_data_file:s0
-/data/misc/perfetto-traces(/.*)? u:object_r:perfetto_traces_data_file:s0
-/data/misc/perfetto-configs(/.*)? u:object_r:perfetto_configs_data_file:s0
-/data/misc/prereboot(/.*)? u:object_r:prereboot_data_file:s0
-/data/misc/profcollectd(/.*)? u:object_r:profcollectd_data_file:s0
-/data/misc/radio(/.*)? u:object_r:radio_core_data_file:s0
-/data/misc/recovery(/.*)? u:object_r:recovery_data_file:s0
-/data/misc/shared_relro(/.*)? u:object_r:shared_relro_file:s0
-/data/misc/sms(/.*)? u:object_r:radio_data_file:s0
-/data/misc/snapshotctl_log(/.*)? u:object_r:snapshotctl_log_data_file:s0
-/data/misc/stats-active-metric(/.*)? u:object_r:stats_data_file:s0
-/data/misc/stats-data(/.*)? u:object_r:stats_data_file:s0
-/data/misc/stats-service(/.*)? u:object_r:stats_data_file:s0
-/data/misc/stats-metadata(/.*)? u:object_r:stats_data_file:s0
-/data/misc/systemkeys(/.*)? u:object_r:systemkeys_data_file:s0
-/data/misc/textclassifier(/.*)? u:object_r:textclassifier_data_file:s0
-/data/misc/train-info(/.*)? u:object_r:stats_data_file:s0
-/data/misc/user(/.*)? u:object_r:misc_user_data_file:s0
-/data/misc/virtualizationservice(/.*)? u:object_r:virtualizationservice_data_file:s0
-/data/misc/vpn(/.*)? u:object_r:vpn_data_file:s0
-/data/misc/wifi(/.*)? u:object_r:wifi_data_file:s0
-/data/misc_ce/[0-9]+/wifi(/.*)? u:object_r:wifi_data_file:s0
-/data/misc/wifi/sockets(/.*)? u:object_r:wpa_socket:s0
-/data/misc/wifi/sockets/wpa_ctrl.* u:object_r:system_wpa_socket:s0
-/data/misc/zoneinfo(/.*)? u:object_r:zoneinfo_data_file:s0
-/data/misc/vold(/.*)? u:object_r:vold_data_file:s0
-/data/misc/iorapd(/.*)? u:object_r:iorapd_data_file:s0
-/data/misc/update_engine(/.*)? u:object_r:update_engine_data_file:s0
-/data/misc/update_engine_log(/.*)? u:object_r:update_engine_log_data_file:s0
-/data/system/dropbox(/.*)? u:object_r:dropbox_data_file:s0
-/data/system/heapdump(/.*)? u:object_r:heapdump_data_file:s0
-/data/misc/trace(/.*)? u:object_r:method_trace_data_file:s0
-/data/misc/wmtrace(/.*)? u:object_r:wm_trace_data_file:s0
-# TODO(calin) label profile reference differently so that only
-# profman run as a special user can write to them
-/data/misc/profiles/cur(/[0-9]+)? u:object_r:user_profile_root_file:s0
-/data/misc/profiles/cur/[0-9]+/.* u:object_r:user_profile_data_file:s0
-/data/misc/profiles/ref(/.*)? u:object_r:user_profile_data_file:s0
-/data/misc/profman(/.*)? u:object_r:profman_dump_data_file:s0
+/data/tombstones(/.*)? u:object_r:tombstone_data_file:s0
/data/vendor(/.*)? u:object_r:vendor_data_file:s0
-/data/vendor_ce(/.*)? u:object_r:vendor_data_file:s0
-/data/vendor_de(/.*)? u:object_r:vendor_data_file:s0
-
-# storaged proto files
-/data/misc_de/[0-9]+/storaged(/.*)? u:object_r:storaged_data_file:s0
-/data/misc_ce/[0-9]+/storaged(/.*)? u:object_r:storaged_data_file:s0
-
-# Fingerprint data
-/data/system/users/[0-9]+/fpdata(/.*)? u:object_r:fingerprintd_data_file:s0
-
-# Fingerprint vendor data file
-/data/vendor_de/[0-9]+/fpdata(/.*)? u:object_r:fingerprint_vendor_data_file:s0
-
-# Face vendor data file
-/data/vendor_de/[0-9]+/facedata(/.*)? u:object_r:face_vendor_data_file:s0
-/data/vendor_ce/[0-9]+/facedata(/.*)? u:object_r:face_vendor_data_file:s0
-
-# Iris vendor data file
-/data/vendor_de/[0-9]+/irisdata(/.*)? u:object_r:iris_vendor_data_file:s0
-
-# Bootchart data
-/data/bootchart(/.*)? u:object_r:bootchart_data_file:s0
-
-# App data snapshots (managed by installd).
-/data/misc_de/[0-9]+/rollback(/.*)? u:object_r:rollback_data_file:s0
-/data/misc_ce/[0-9]+/rollback(/.*)? u:object_r:rollback_data_file:s0
-
-# Apex data directories
-/data/misc_de/[0-9]+/apexdata(/.*)? u:object_r:apex_module_data_file:s0
-/data/misc_ce/[0-9]+/apexdata(/.*)? u:object_r:apex_module_data_file:s0
-/data/misc_ce/[0-9]+/apexdata/com\.android\.appsearch(/.*)? u:object_r:apex_appsearch_data_file:s0
-/data/misc_de/[0-9]+/apexdata/com\.android\.permission(/.*)? u:object_r:apex_permission_data_file:s0
-/data/misc_ce/[0-9]+/apexdata/com\.android\.permission(/.*)? u:object_r:apex_permission_data_file:s0
-/data/misc_de/[0-9]+/apexdata/com\.android\.wifi(/.*)? u:object_r:apex_wifi_data_file:s0
-/data/misc_ce/[0-9]+/apexdata/com\.android\.wifi(/.*)? u:object_r:apex_wifi_data_file:s0
-
-# Apex rollback directories
-/data/misc_de/[0-9]+/apexrollback(/.*)? u:object_r:apex_rollback_data_file:s0
-/data/misc_ce/[0-9]+/apexrollback(/.*)? u:object_r:apex_rollback_data_file:s0
-
-# Incremental directories
-/data/incremental(/.*)? u:object_r:apk_data_file:s0
-/data/incremental/MT_[^/]+/mount/.pending_reads u:object_r:incremental_control_file:s0
-/data/incremental/MT_[^/]+/mount/.log u:object_r:incremental_control_file:s0
-/data/incremental/MT_[^/]+/mount/.blocks_written u:object_r:incremental_control_file:s0
-
-#############################
-# Expanded data files
-#
-/mnt/expand(/.*)? u:object_r:mnt_expand_file:s0
-/mnt/expand/[^/]+(/.*)? u:object_r:system_data_file:s0
-/mnt/expand/[^/]+/app(/.*)? u:object_r:apk_data_file:s0
-/mnt/expand/[^/]+/app/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
-# /mnt/expand/..../app/[randomStringA]/[packageName]-[randomStringB]/base.apk layout
-/mnt/expand/[^/]+/app/[^/]+/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
-/mnt/expand/[^/]+/app/vmdl[^/]+\.tmp(/.*)? u:object_r:apk_tmp_file:s0
-/mnt/expand/[^/]+/app/vmdl[^/]+\.tmp/oat(/.*)? u:object_r:dalvikcache_data_file:s0
-/mnt/expand/[^/]+/local/tmp(/.*)? u:object_r:shell_data_file:s0
-/mnt/expand/[^/]+/media(/.*)? u:object_r:media_rw_data_file:s0
-/mnt/expand/[^/]+/misc/vold(/.*)? u:object_r:vold_data_file:s0
-
-# coredump directory for userdebug/eng devices
-/cores(/.*)? u:object_r:coredump_file:s0
-
-# Wallpaper files
-/data/system/users/[0-9]+/wallpaper_lock_orig u:object_r:wallpaper_file:s0
-/data/system/users/[0-9]+/wallpaper_lock u:object_r:wallpaper_file:s0
-/data/system/users/[0-9]+/wallpaper_orig u:object_r:wallpaper_file:s0
-/data/system/users/[0-9]+/wallpaper u:object_r:wallpaper_file:s0
-
-# Ringtone files
-/data/system_de/[0-9]+/ringtones(/.*)? u:object_r:ringtone_file:s0
-
-# ShortcutManager icons, e.g.
-# /data/system_ce/0/shortcut_service/bitmaps/com.example.app/1457472879282.png
-/data/system_ce/[0-9]+/shortcut_service/bitmaps(/.*)? u:object_r:shortcut_manager_icons:s0
-
-# User icon files
-/data/system/users/[0-9]+/photo\.png u:object_r:icon_file:s0
-
-# vold per-user data
-/data/misc_de/[0-9]+/vold(/.*)? u:object_r:vold_data_file:s0
-/data/misc_ce/[0-9]+/vold(/.*)? u:object_r:vold_data_file:s0
-
-# iorapd per-user data
-/data/misc_ce/[0-9]+/iorapd(/.*)? u:object_r:iorapd_data_file:s0
-
-# Backup service persistent per-user bookkeeping
-/data/system_ce/[0-9]+/backup(/.*)? u:object_r:backup_data_file:s0
-# Backup service temporary per-user data for inter-change with apps
-/data/system_ce/[0-9]+/backup_stage(/.*)? u:object_r:backup_data_file:s0
-
-#############################
-# efs files
-#
-/efs(/.*)? u:object_r:efs_file:s0
-
-#############################
-# Cache files
-#
-/cache(/.*)? u:object_r:cache_file:s0
-/cache/recovery(/.*)? u:object_r:cache_recovery_file:s0
-# General backup/restore interchange with apps
-/cache/backup_stage(/.*)? u:object_r:cache_backup_file:s0
-# LocalTransport (backup) uses this subtree
-/cache/backup(/.*)? u:object_r:cache_private_backup_file:s0
-
-#############################
-# Overlayfs support directories
-#
-/cache/overlay(/.*)? u:object_r:overlayfs_file:s0
-/mnt/scratch(/.*)? u:object_r:overlayfs_file:s0
-
-/data/cache(/.*)? u:object_r:cache_file:s0
-/data/cache/recovery(/.*)? u:object_r:cache_recovery_file:s0
-# General backup/restore interchange with apps
-/data/cache/backup_stage(/.*)? u:object_r:cache_backup_file:s0
-# LocalTransport (backup) uses this subtree
-/data/cache/backup(/.*)? u:object_r:cache_private_backup_file:s0
-
-#############################
-# Metadata files
-#
-/metadata(/.*)? u:object_r:metadata_file:s0
-/metadata/apex(/.*)? u:object_r:apex_metadata_file:s0
-/metadata/vold(/.*)? u:object_r:vold_metadata_file:s0
-/metadata/gsi(/.*)? u:object_r:gsi_metadata_file:s0
-/metadata/gsi/dsu/active u:object_r:gsi_public_metadata_file:s0
-/metadata/gsi/dsu/booted u:object_r:gsi_public_metadata_file:s0
-/metadata/gsi/dsu/lp_names u:object_r:gsi_public_metadata_file:s0
-/metadata/gsi/dsu/[^/]+/metadata_encryption_dir u:object_r:gsi_public_metadata_file:s0
-/metadata/gsi/ota(/.*)? u:object_r:ota_metadata_file:s0
-/metadata/password_slots(/.*)? u:object_r:password_slot_metadata_file:s0
-/metadata/ota(/.*)? u:object_r:ota_metadata_file:s0
-/metadata/bootstat(/.*)? u:object_r:metadata_bootstat_file:s0
-/metadata/staged-install(/.*)? u:object_r:staged_install_file:s0
-/metadata/userspacereboot(/.*)? u:object_r:userspace_reboot_metadata_file:s0
-/metadata/watchdog(/.*)? u:object_r:watchdog_metadata_file:s0
-
-#############################
-# asec containers
-/mnt/asec(/.*)? u:object_r:asec_apk_file:s0
-/mnt/asec/[^/]+/[^/]+\.zip u:object_r:asec_public_file:s0
-/mnt/asec/[^/]+/lib(/.*)? u:object_r:asec_public_file:s0
-/data/app-asec(/.*)? u:object_r:asec_image_file:s0
-
-#############################
-# external storage
-/mnt/media_rw(/.*)? u:object_r:mnt_media_rw_file:s0
-/mnt/user(/.*)? u:object_r:mnt_user_file:s0
-/mnt/pass_through(/.*)? u:object_r:mnt_pass_through_file:s0
-/mnt/sdcard u:object_r:mnt_sdcard_file:s0
-/mnt/runtime(/.*)? u:object_r:storage_file:s0
-/storage(/.*)? u:object_r:storage_file:s0
-
-#############################
-# mount point for read-write vendor partitions
-/mnt/vendor(/.*)? u:object_r:mnt_vendor_file:s0
-
-#############################
-# mount point for read-write product partitions
-/mnt/product(/.*)? u:object_r:mnt_product_file:s0
-
-#############################
-# /postinstall file contexts
-/(system|product)/bin/check_dynamic_partitions u:object_r:postinstall_exec:s0
-/(system|product)/bin/otapreopt_script u:object_r:postinstall_exec:s0
-/(system|product)/bin/otapreopt u:object_r:postinstall_dexopt_exec:s0
diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index f5ad1f8..700d0fc 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -2,8 +2,8 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-rust_binary {
- name: "virtualizationservice",
+rust_defaults {
+ name: "virtualizationservice_defaults",
crate_name: "virtualizationservice",
srcs: ["src/main.rs"],
edition: "2018",
@@ -24,12 +24,26 @@
"libandroid_logger",
"libanyhow",
"libcommand_fds",
- "libcompositediskconfig",
+ "libcrc32fast",
"libdisk",
"liblog_rust",
+ "libprotobuf",
+ "libprotos",
"libserde_json",
"libserde",
"libshared_child",
+ "libuuid",
],
+}
+
+rust_binary {
+ name: "virtualizationservice",
+ defaults: ["virtualizationservice_defaults"],
apex_available: ["com.android.virt"],
}
+
+rust_test {
+ name: "virtualizationservice_device_test",
+ defaults: ["virtualizationservice_defaults"],
+ test_suites: ["general-tests"],
+}
diff --git a/virtualizationservice/TEST_MAPPING b/virtualizationservice/TEST_MAPPING
new file mode 100644
index 0000000..6456a98
--- /dev/null
+++ b/virtualizationservice/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "virtualizationservice_device_test"
+ }
+ ]
+}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 6d3f737..0089bfc 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -227,16 +227,21 @@
));
}
- let composite_image_filename =
- make_composite_image_filename(temporary_directory, next_temporary_image_id);
- let (image, partition_files) =
- make_composite_image(&disk.partitions, &composite_image_filename).map_err(|e| {
- error!("Failed to make composite image with config {:?}: {}", disk, e);
- new_binder_exception(
- ExceptionCode::SERVICE_SPECIFIC,
- format!("Failed to make composite image: {}", e),
- )
- })?;
+ let composite_image_filenames =
+ make_composite_image_filenames(temporary_directory, next_temporary_image_id);
+ let (image, partition_files) = make_composite_image(
+ &disk.partitions,
+ &composite_image_filenames.composite,
+ &composite_image_filenames.header,
+ &composite_image_filenames.footer,
+ )
+ .map_err(|e| {
+ error!("Failed to make composite image with config {:?}: {}", disk, e);
+ new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("Failed to make composite image: {}", e),
+ )
+ })?;
// Pass the file descriptors for the various partition files to crosvm when it
// is run.
@@ -257,13 +262,28 @@
}
/// Generates a unique filename to use for a composite disk image.
-fn make_composite_image_filename(
+fn make_composite_image_filenames(
temporary_directory: &Path,
next_temporary_image_id: &mut u64,
-) -> PathBuf {
+) -> CompositeImageFilenames {
let id = *next_temporary_image_id;
*next_temporary_image_id += 1;
- temporary_directory.join(format!("composite-{}.img", id))
+ CompositeImageFilenames {
+ composite: temporary_directory.join(format!("composite-{}.img", id)),
+ header: temporary_directory.join(format!("composite-{}-header.img", id)),
+ footer: temporary_directory.join(format!("composite-{}-footer.img", id)),
+ }
+}
+
+/// Filenames for a composite disk image, including header and footer partitions.
+#[derive(Clone, Debug, Eq, PartialEq)]
+struct CompositeImageFilenames {
+ /// The composite disk image itself.
+ composite: PathBuf,
+ /// The header partition image.
+ header: PathBuf,
+ /// The footer partition image.
+ footer: PathBuf,
}
/// Gets the calling SID of the current Binder thread.
diff --git a/virtualizationservice/src/composite.rs b/virtualizationservice/src/composite.rs
index 37428eb..5f792fd 100644
--- a/virtualizationservice/src/composite.rs
+++ b/virtualizationservice/src/composite.rs
@@ -12,76 +12,334 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-//! Functions for running `mk_cdisk`.
+//! Functions for creating a composite disk image.
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::Partition::Partition as AidlPartition;
-use anyhow::{bail, Context, Error};
-use command_fds::{CommandFdExt, FdMapping};
-use compositediskconfig::{Config, Partition};
-use log::info;
-use std::fs::File;
+use crate::gpt::{
+ write_gpt_header, write_protective_mbr, GptPartitionEntry, GPT_BEGINNING_SIZE, GPT_END_SIZE,
+ GPT_HEADER_SIZE, GPT_NUM_PARTITIONS, GPT_PARTITION_ENTRY_SIZE, SECTOR_SIZE,
+};
+use android_system_virtualizationservice::aidl::android::system::virtualizationservice::Partition::Partition;
+use anyhow::{anyhow, bail, Context, Error};
+use crc32fast::Hasher;
+use disk::create_disk_file;
+use log::{trace, warn};
+use protobuf::Message;
+use protos::cdisk_spec::{ComponentDisk, CompositeDisk, ReadWriteCapability};
+use std::convert::TryInto;
+use std::fs::{File, OpenOptions};
+use std::io::Write;
use std::os::unix::io::AsRawFd;
-use std::panic;
-use std::path::Path;
-use std::process::{Command, Stdio};
-use std::str;
-use std::thread;
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
-const MK_CDISK_PATH: &str = "/apex/com.android.virt/bin/mk_cdisk";
+/// A magic string placed at the beginning of a composite disk file to identify it.
+const CDISK_MAGIC: &str = "composite_disk\x1d";
+/// The version of the composite disk format supported by this implementation.
+const COMPOSITE_DISK_VERSION: u64 = 1;
+/// The amount of padding needed between the last partition entry and the first partition, to align
+/// the partition appropriately. The two sectors are for the MBR and the GPT header.
+const PARTITION_ALIGNMENT_SIZE: usize = GPT_BEGINNING_SIZE as usize
+ - 2 * SECTOR_SIZE as usize
+ - GPT_NUM_PARTITIONS as usize * GPT_PARTITION_ENTRY_SIZE as usize;
+const HEADER_PADDING_LENGTH: usize = SECTOR_SIZE as usize - GPT_HEADER_SIZE as usize;
+// Keep all partitions 4k aligned for performance.
+const PARTITION_SIZE_SHIFT: u8 = 12;
+// Keep the disk size a multiple of 64k for crosvm's virtio_blk driver.
+const DISK_SIZE_SHIFT: u8 = 16;
-/// Calls `mk_cdisk` to construct a composite disk image for the given list of partitions, and opens
-/// it ready to use. Returns the composite disk image file, and a list of FD mappings which must be
-/// applied to any process which wants to use it. This is necessary because the composite image
-/// contains paths of the form `/proc/self/fd/N` for the partition images.
-pub fn make_composite_image(
- partitions: &[AidlPartition],
- output_filename: &Path,
-) -> Result<(File, Vec<File>), Error> {
- let (config_json, files) = make_config_json(partitions)?;
- let fd_mappings: Vec<_> = files
- .iter()
- .map(|file| FdMapping { parent_fd: file.as_raw_fd(), child_fd: file.as_raw_fd() })
- .collect();
+const LINUX_FILESYSTEM_GUID: Uuid = Uuid::from_u128(0x0FC63DAF_8483_4772_8E79_3D69D8477DE4);
+const EFI_SYSTEM_PARTITION_GUID: Uuid = Uuid::from_u128(0xC12A7328_F81F_11D2_BA4B_00A0C93EC93B);
- let mut command = Command::new(MK_CDISK_PATH);
- command
- .arg("-") // Read config JSON from stdin.
- .arg(&output_filename)
- .stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped());
- command.fd_mappings(fd_mappings)?;
- let mut child = command.spawn().context("Failed to spawn mk_cdisk")?;
- let stdin = child.stdin.take().unwrap();
+/// Information about a single image file to be included in a partition.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct PartitionFileInfo {
+ path: PathBuf,
+ size: u64,
+}
- // Write config to stdin of mk_cdisk on a separate thread to avoid deadlock, as it may not read
- // all of stdin before it blocks on writing to stdout.
- let writer_thread = thread::spawn(move || {
- config_json.write_json(&stdin).context("Failed to write config JSON for mk_cdisk")
+/// Information about a partition to create, including the set of image files which make it up.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct PartitionInfo {
+ label: String,
+ files: Vec<PartitionFileInfo>,
+ partition_type: ImagePartitionType,
+ writable: bool,
+}
+
+/// Round `val` up to the next multiple of 2**`align_log`.
+fn align_to_power_of_2(val: u64, align_log: u8) -> u64 {
+ let align = 1 << align_log;
+ ((val + (align - 1)) / align) * align
+}
+
+impl PartitionInfo {
+ fn aligned_size(&self) -> u64 {
+ align_to_power_of_2(self.files.iter().map(|file| file.size).sum(), PARTITION_SIZE_SHIFT)
+ }
+}
+
+/// The type of partition.
+#[allow(dead_code)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum ImagePartitionType {
+ LinuxFilesystem,
+ EfiSystemPartition,
+}
+
+impl ImagePartitionType {
+ fn guid(self) -> Uuid {
+ match self {
+ Self::LinuxFilesystem => LINUX_FILESYSTEM_GUID,
+ Self::EfiSystemPartition => EFI_SYSTEM_PARTITION_GUID,
+ }
+ }
+}
+
+/// Write protective MBR and primary GPT table.
+fn write_beginning(
+ file: &mut impl Write,
+ disk_guid: Uuid,
+ partitions: &[u8],
+ partition_entries_crc32: u32,
+ secondary_table_offset: u64,
+ disk_size: u64,
+) -> Result<(), Error> {
+ // Write the protective MBR to the first sector.
+ write_protective_mbr(file, disk_size)?;
+
+ // Write the GPT header, and pad out to the end of the sector.
+ write_gpt_header(file, disk_guid, partition_entries_crc32, secondary_table_offset, false)?;
+ file.write_all(&[0; HEADER_PADDING_LENGTH])?;
+
+ // Write partition entries, including unused ones.
+ file.write_all(partitions)?;
+
+ // Write zeroes to align the first partition appropriately.
+ file.write_all(&[0; PARTITION_ALIGNMENT_SIZE])?;
+
+ Ok(())
+}
+
+/// Write secondary GPT table.
+fn write_end(
+ file: &mut impl Write,
+ disk_guid: Uuid,
+ partitions: &[u8],
+ partition_entries_crc32: u32,
+ secondary_table_offset: u64,
+ disk_size: u64,
+) -> Result<(), Error> {
+ // Write partition entries, including unused ones.
+ file.write_all(partitions)?;
+
+ // Write the GPT header, and pad out to the end of the sector.
+ write_gpt_header(file, disk_guid, partition_entries_crc32, secondary_table_offset, true)?;
+ file.write_all(&[0; HEADER_PADDING_LENGTH])?;
+
+ // Pad out to the aligned disk size.
+ let used_disk_size = secondary_table_offset + GPT_END_SIZE;
+ let padding = disk_size - used_disk_size;
+ file.write_all(&vec![0; padding as usize])?;
+
+ Ok(())
+}
+
+/// Create the `GptPartitionEntry` for the given partition.
+fn create_gpt_entry(partition: &PartitionInfo, offset: u64) -> GptPartitionEntry {
+ let mut partition_name: Vec<u16> = partition.label.encode_utf16().collect();
+ partition_name.resize(36, 0);
+
+ GptPartitionEntry {
+ partition_type_guid: partition.partition_type.guid(),
+ unique_partition_guid: Uuid::new_v4(),
+ first_lba: offset / SECTOR_SIZE,
+ last_lba: (offset + partition.aligned_size()) / SECTOR_SIZE - 1,
+ attributes: 0,
+ partition_name: partition_name.try_into().unwrap(),
+ }
+}
+
+/// Create one or more `ComponentDisk` proto messages for the given partition.
+fn create_component_disks(
+ partition: &PartitionInfo,
+ offset: u64,
+ header_path: &str,
+) -> Result<Vec<ComponentDisk>, Error> {
+ let aligned_size = partition.aligned_size();
+
+ if partition.files.is_empty() {
+ bail!("No image files for partition {:?}", partition);
+ }
+ let mut file_size_sum = 0;
+ let mut component_disks = vec![];
+ for file in &partition.files {
+ component_disks.push(ComponentDisk {
+ offset: offset + file_size_sum,
+ file_path: file.path.to_str().context("Invalid partition path")?.to_string(),
+ read_write_capability: if partition.writable {
+ ReadWriteCapability::READ_WRITE
+ } else {
+ ReadWriteCapability::READ_ONLY
+ },
+ ..ComponentDisk::new()
+ });
+ file_size_sum += file.size;
+ }
+
+ if file_size_sum != aligned_size {
+ if partition.writable {
+ bail!(
+ "Read-write partition {:?} size is not a multiple of {}.",
+ partition,
+ 1 << PARTITION_SIZE_SHIFT
+ );
+ } else {
+ // Fill in the gap by reusing the header file, because we know it is always bigger
+ // than the alignment size (i.e. GPT_BEGINNING_SIZE > 1 << PARTITION_SIZE_SHIFT).
+ warn!(
+ "Read-only partition {:?} size is not a multiple of {}, filling gap.",
+ partition,
+ 1 << PARTITION_SIZE_SHIFT
+ );
+ component_disks.push(ComponentDisk {
+ offset: offset + file_size_sum,
+ file_path: header_path.to_owned(),
+ read_write_capability: ReadWriteCapability::READ_ONLY,
+ ..ComponentDisk::new()
+ });
+ }
+ }
+
+ Ok(component_disks)
+}
+
+/// Create a new composite disk containing the given partitions, and write it out to the given
+/// files.
+pub fn create_composite_disk(
+ partitions: &[PartitionInfo],
+ header_path: &Path,
+ header_file: &mut File,
+ footer_path: &Path,
+ footer_file: &mut File,
+ output_composite: &mut File,
+) -> Result<(), Error> {
+ let header_path = header_path.to_str().context("Invalid header path")?.to_string();
+ let footer_path = footer_path.to_str().context("Invalid footer path")?.to_string();
+
+ let mut composite_proto = CompositeDisk::new();
+ composite_proto.version = COMPOSITE_DISK_VERSION;
+ composite_proto.component_disks.push(ComponentDisk {
+ file_path: header_path.clone(),
+ offset: 0,
+ read_write_capability: ReadWriteCapability::READ_ONLY,
+ ..ComponentDisk::new()
});
- info!("Running {:?}", command);
- let output = child.wait_with_output()?;
- match writer_thread.join() {
- Ok(result) => result?,
- Err(panic_payload) => panic::resume_unwind(panic_payload),
- }
- if !output.status.success() {
- info!("mk_cdisk stdout: {}", str::from_utf8(&output.stdout)?);
- info!("mk_cdisk stderr: {}", str::from_utf8(&output.stderr)?);
- bail!("mk_cdisk exited with error {}", output.status);
- }
+ // Write partitions to a temporary buffer so that we can calculate the CRC, and construct the
+ // ComponentDisk proto messages at the same time.
+ let mut partitions_buffer =
+ [0u8; GPT_NUM_PARTITIONS as usize * GPT_PARTITION_ENTRY_SIZE as usize];
+ let mut writer: &mut [u8] = &mut partitions_buffer;
+ let mut next_disk_offset = GPT_BEGINNING_SIZE;
+ for partition in partitions {
+ create_gpt_entry(partition, next_disk_offset).write_bytes(&mut writer)?;
- let composite_image = File::open(&output_filename)
- .with_context(|| format!("Failed to open composite image {:?}", output_filename))?;
+ for component_disk in create_component_disks(partition, next_disk_offset, &header_path)? {
+ composite_proto.component_disks.push(component_disk);
+ }
+
+ next_disk_offset += partition.aligned_size();
+ }
+ let secondary_table_offset = next_disk_offset;
+ let disk_size = align_to_power_of_2(secondary_table_offset + GPT_END_SIZE, DISK_SIZE_SHIFT);
+ trace!("Partitions: {:#?}", partitions);
+ trace!("Secondary table offset: {} disk size: {}", secondary_table_offset, disk_size);
+
+ composite_proto.component_disks.push(ComponentDisk {
+ file_path: footer_path,
+ offset: secondary_table_offset,
+ read_write_capability: ReadWriteCapability::READ_ONLY,
+ ..ComponentDisk::new()
+ });
+
+ // Calculate CRC32 of partition entries.
+ let mut hasher = Hasher::new();
+ hasher.update(&partitions_buffer);
+ let partition_entries_crc32 = hasher.finalize();
+
+ let disk_guid = Uuid::new_v4();
+ write_beginning(
+ header_file,
+ disk_guid,
+ &partitions_buffer,
+ partition_entries_crc32,
+ secondary_table_offset,
+ disk_size,
+ )?;
+ write_end(
+ footer_file,
+ disk_guid,
+ &partitions_buffer,
+ partition_entries_crc32,
+ secondary_table_offset,
+ disk_size,
+ )?;
+
+ composite_proto.length = disk_size;
+ output_composite.write_all(CDISK_MAGIC.as_bytes())?;
+ composite_proto.write_to_writer(output_composite)?;
+
+ Ok(())
+}
+
+/// Constructs a composite disk image for the given list of partitions, and opens it ready to use.
+///
+/// Returns the composite disk image file, and a list of FD mappings which must be applied to any
+/// process which wants to use it. This is necessary because the composite image contains paths of
+/// the form `/proc/self/fd/N` for the partition images.
+pub fn make_composite_image(
+ partitions: &[Partition],
+ output_path: &Path,
+ header_path: &Path,
+ footer_path: &Path,
+) -> Result<(File, Vec<File>), Error> {
+ let (partitions, files) = convert_partitions(partitions)?;
+
+ let mut composite_image = OpenOptions::new()
+ .create_new(true)
+ .read(true)
+ .write(true)
+ .open(output_path)
+ .with_context(|| format!("Failed to create composite image {:?}", output_path))?;
+ let mut header_file =
+ OpenOptions::new().create_new(true).read(true).write(true).open(header_path).with_context(
+ || format!("Failed to create composite image header {:?}", header_path),
+ )?;
+ let mut footer_file =
+ OpenOptions::new().create_new(true).read(true).write(true).open(footer_path).with_context(
+ || format!("Failed to create composite image header {:?}", footer_path),
+ )?;
+
+ create_composite_disk(
+ &partitions,
+ header_path,
+ &mut header_file,
+ footer_path,
+ &mut footer_file,
+ &mut composite_image,
+ )?;
+
+ // Re-open the composite image as read-only.
+ let composite_image = File::open(&output_path)
+ .with_context(|| format!("Failed to open composite image {:?}", output_path))?;
Ok((composite_image, files))
}
/// Given the AIDL config containing a list of partitions, with a [`ParcelFileDescriptor`] for each
/// partition, return the list of file descriptors which must be passed to the mk_cdisk child
-/// process and the JSON configuration for it.
-fn make_config_json(partitions: &[AidlPartition]) -> Result<(Config, Vec<File>), Error> {
+/// process and the composite disk image partition configuration for it.
+fn convert_partitions(partitions: &[Partition]) -> Result<(Vec<PartitionInfo>, Vec<File>), Error> {
// File descriptors to pass to child process.
let mut files = vec![];
@@ -96,17 +354,91 @@
.as_ref()
.try_clone()
.context("Failed to clone partition image file descriptor")?;
+ let size = get_partition_size(&file)?;
let fd = file.as_raw_fd();
files.push(file);
- Ok(Partition {
- writable: partition.writable,
+ Ok(PartitionInfo {
label: partition.label.to_owned(),
- path: format!("/proc/self/fd/{}", fd).into(),
+ files: vec![PartitionFileInfo {
+ path: format!("/proc/self/fd/{}", fd).into(),
+ size,
+ }],
+ partition_type: ImagePartitionType::LinuxFilesystem,
+ writable: partition.writable,
})
})
.collect::<Result<_, Error>>()?;
- let config_json = Config { partitions };
- Ok((config_json, files))
+ Ok((partitions, files))
+}
+
+/// Find the size of the partition image in the given file by parsing the header.
+///
+/// This will work for raw, QCOW2, composite and Android sparse images.
+fn get_partition_size(partition: &File) -> Result<u64, Error> {
+ // TODO: Use `context` once disk::Error implements std::error::Error.
+ Ok(create_disk_file(partition.try_clone()?)
+ .map_err(|e| anyhow!("Failed to open partition image: {}", e))?
+ .get_len()?)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn beginning_size() {
+ let mut buffer = vec![];
+ let partitions = [0u8; GPT_NUM_PARTITIONS as usize * GPT_PARTITION_ENTRY_SIZE as usize];
+ let disk_size = 1000 * SECTOR_SIZE;
+ write_beginning(
+ &mut buffer,
+ Uuid::from_u128(0x12345678_1234_5678_abcd_12345678abcd),
+ &partitions,
+ 42,
+ disk_size - GPT_END_SIZE,
+ disk_size,
+ )
+ .unwrap();
+
+ assert_eq!(buffer.len(), GPT_BEGINNING_SIZE as usize);
+ }
+
+ #[test]
+ fn end_size() {
+ let mut buffer = vec![];
+ let partitions = [0u8; GPT_NUM_PARTITIONS as usize * GPT_PARTITION_ENTRY_SIZE as usize];
+ let disk_size = 1000 * SECTOR_SIZE;
+ write_end(
+ &mut buffer,
+ Uuid::from_u128(0x12345678_1234_5678_abcd_12345678abcd),
+ &partitions,
+ 42,
+ disk_size - GPT_END_SIZE,
+ disk_size,
+ )
+ .unwrap();
+
+ assert_eq!(buffer.len(), GPT_END_SIZE as usize);
+ }
+
+ #[test]
+ fn end_size_with_padding() {
+ let mut buffer = vec![];
+ let partitions = [0u8; GPT_NUM_PARTITIONS as usize * GPT_PARTITION_ENTRY_SIZE as usize];
+ let disk_size = 1000 * SECTOR_SIZE;
+ let padding = 3 * SECTOR_SIZE;
+ write_end(
+ &mut buffer,
+ Uuid::from_u128(0x12345678_1234_5678_abcd_12345678abcd),
+ &partitions,
+ 42,
+ disk_size - GPT_END_SIZE - padding,
+ disk_size,
+ )
+ .unwrap();
+
+ assert_eq!(buffer.len(), GPT_END_SIZE as usize + padding as usize);
+ }
}
diff --git a/virtualizationservice/src/gpt.rs b/virtualizationservice/src/gpt.rs
new file mode 100644
index 0000000..346a40a
--- /dev/null
+++ b/virtualizationservice/src/gpt.rs
@@ -0,0 +1,240 @@
+// Copyright 2021, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Functions for writing GUID Partition Tables for use in a composite disk image.
+
+use anyhow::Error;
+use crc32fast::Hasher;
+use std::convert::TryInto;
+use std::io::Write;
+use uuid::Uuid;
+
+/// The size in bytes of a disk sector (also called a block).
+pub const SECTOR_SIZE: u64 = 1 << 9;
+/// The size in bytes on an MBR partition entry.
+const MBR_PARTITION_ENTRY_SIZE: usize = 16;
+/// The size in bytes of a GPT header.
+pub const GPT_HEADER_SIZE: u32 = 92;
+/// The number of partition entries in the GPT, which is the maximum number of partitions which are
+/// supported.
+pub const GPT_NUM_PARTITIONS: u32 = 128;
+/// The size in bytes of a single GPT partition entry.
+pub const GPT_PARTITION_ENTRY_SIZE: u32 = 128;
+/// The size in bytes of everything before the first partition: i.e. the MBR, GPT header and GPT
+/// partition entries.
+pub const GPT_BEGINNING_SIZE: u64 = SECTOR_SIZE * 40;
+/// The size in bytes of everything after the last partition: i.e. the GPT partition entries and GPT
+/// footer.
+pub const GPT_END_SIZE: u64 = SECTOR_SIZE * 33;
+
+/// Write a protective MBR for a disk of the given total size (in bytes).
+///
+/// This should be written at the start of the disk, before the GPT header. It
+/// is one `SECTOR_SIZE` long.
+pub fn write_protective_mbr(file: &mut impl Write, disk_size: u64) -> Result<(), Error> {
+ // Bootstrap code
+ file.write_all(&[0; 446])?;
+
+ // Partition status
+ file.write_all(&[0x00])?;
+ // Begin CHS
+ file.write_all(&[0; 3])?;
+ // Partition type
+ file.write_all(&[0xEE])?;
+ // End CHS
+ file.write_all(&[0; 3])?;
+ let first_lba: u32 = 1;
+ file.write_all(&first_lba.to_le_bytes())?;
+ let number_of_sectors: u32 = (disk_size / SECTOR_SIZE).try_into()?;
+ file.write_all(&number_of_sectors.to_le_bytes())?;
+
+ // Three more empty partitions
+ file.write_all(&[0; MBR_PARTITION_ENTRY_SIZE * 3])?;
+
+ // Boot signature
+ file.write_all(&[0x55, 0xAA])?;
+
+ Ok(())
+}
+
+#[derive(Clone, Debug, Default, Eq, PartialEq)]
+struct GptHeader {
+ signature: [u8; 8],
+ revision: [u8; 4],
+ header_size: u32,
+ header_crc32: u32,
+ current_lba: u64,
+ backup_lba: u64,
+ first_usable_lba: u64,
+ last_usable_lba: u64,
+ disk_guid: Uuid,
+ partition_entries_lba: u64,
+ num_partition_entries: u32,
+ partition_entry_size: u32,
+ partition_entries_crc32: u32,
+}
+
+impl GptHeader {
+ fn write_bytes(&self, out: &mut impl Write) -> Result<(), Error> {
+ out.write_all(&self.signature)?;
+ out.write_all(&self.revision)?;
+ out.write_all(&self.header_size.to_le_bytes())?;
+ out.write_all(&self.header_crc32.to_le_bytes())?;
+ // Reserved
+ out.write_all(&[0; 4])?;
+ out.write_all(&self.current_lba.to_le_bytes())?;
+ out.write_all(&self.backup_lba.to_le_bytes())?;
+ out.write_all(&self.first_usable_lba.to_le_bytes())?;
+ out.write_all(&self.last_usable_lba.to_le_bytes())?;
+
+ // GUID is mixed-endian for some reason, so we can't just use `Uuid::as_bytes()`.
+ write_guid(out, self.disk_guid)?;
+
+ out.write_all(&self.partition_entries_lba.to_le_bytes())?;
+ out.write_all(&self.num_partition_entries.to_le_bytes())?;
+ out.write_all(&self.partition_entry_size.to_le_bytes())?;
+ out.write_all(&self.partition_entries_crc32.to_le_bytes())?;
+ Ok(())
+ }
+}
+
+/// Write a GPT header for the disk.
+///
+/// It may either be a primary header (which should go at LBA 1) or a secondary header (which should
+/// go at the end of the disk).
+pub fn write_gpt_header(
+ out: &mut impl Write,
+ disk_guid: Uuid,
+ partition_entries_crc32: u32,
+ secondary_table_offset: u64,
+ secondary: bool,
+) -> Result<(), Error> {
+ let primary_header_lba = 1;
+ let secondary_header_lba = (secondary_table_offset + GPT_END_SIZE) / SECTOR_SIZE - 1;
+ let mut gpt_header = GptHeader {
+ signature: *b"EFI PART",
+ revision: [0, 0, 1, 0],
+ header_size: GPT_HEADER_SIZE,
+ current_lba: if secondary { secondary_header_lba } else { primary_header_lba },
+ backup_lba: if secondary { primary_header_lba } else { secondary_header_lba },
+ first_usable_lba: GPT_BEGINNING_SIZE / SECTOR_SIZE,
+ last_usable_lba: secondary_table_offset / SECTOR_SIZE - 1,
+ disk_guid,
+ partition_entries_lba: 2,
+ num_partition_entries: GPT_NUM_PARTITIONS,
+ partition_entry_size: GPT_PARTITION_ENTRY_SIZE,
+ partition_entries_crc32,
+ header_crc32: 0,
+ };
+
+ // Write once to a temporary buffer to calculate the CRC.
+ let mut header_without_crc = [0u8; GPT_HEADER_SIZE as usize];
+ gpt_header.write_bytes(&mut &mut header_without_crc[..])?;
+ let mut hasher = Hasher::new();
+ hasher.update(&header_without_crc);
+ gpt_header.header_crc32 = hasher.finalize();
+
+ gpt_header.write_bytes(out)?;
+
+ Ok(())
+}
+
+/// A GPT entry for a particular partition.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct GptPartitionEntry {
+ pub partition_type_guid: Uuid,
+ pub unique_partition_guid: Uuid,
+ pub first_lba: u64,
+ pub last_lba: u64,
+ pub attributes: u64,
+ /// UTF-16LE
+ pub partition_name: [u16; 36],
+}
+
+// TODO: Derive this once arrays of more than 32 elements have default values.
+impl Default for GptPartitionEntry {
+ fn default() -> Self {
+ Self {
+ partition_type_guid: Default::default(),
+ unique_partition_guid: Default::default(),
+ first_lba: 0,
+ last_lba: 0,
+ attributes: 0,
+ partition_name: [0; 36],
+ }
+ }
+}
+
+impl GptPartitionEntry {
+ /// Write out the partition table entry. It will take
+ /// `GPT_PARTITION_ENTRY_SIZE` bytes.
+ pub fn write_bytes(&self, out: &mut impl Write) -> Result<(), Error> {
+ write_guid(out, self.partition_type_guid)?;
+ write_guid(out, self.unique_partition_guid)?;
+ out.write_all(&self.first_lba.to_le_bytes())?;
+ out.write_all(&self.last_lba.to_le_bytes())?;
+ out.write_all(&self.attributes.to_le_bytes())?;
+ for code_unit in &self.partition_name {
+ out.write_all(&code_unit.to_le_bytes())?;
+ }
+ Ok(())
+ }
+}
+
+/// Write a UUID in the mixed-endian format which GPT uses for GUIDs.
+fn write_guid(out: &mut impl Write, guid: Uuid) -> Result<(), Error> {
+ let guid_fields = guid.as_fields();
+ out.write_all(&guid_fields.0.to_le_bytes())?;
+ out.write_all(&guid_fields.1.to_le_bytes())?;
+ out.write_all(&guid_fields.2.to_le_bytes())?;
+ out.write_all(guid_fields.3)?;
+
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn protective_mbr_size() {
+ let mut buffer = vec![];
+ write_protective_mbr(&mut buffer, 1000 * SECTOR_SIZE).unwrap();
+
+ assert_eq!(buffer.len(), SECTOR_SIZE as usize);
+ }
+
+ #[test]
+ fn header_size() {
+ let mut buffer = vec![];
+ write_gpt_header(
+ &mut buffer,
+ Uuid::from_u128(0x12345678_1234_5678_abcd_12345678abcd),
+ 42,
+ 1000 * SECTOR_SIZE,
+ false,
+ )
+ .unwrap();
+
+ assert_eq!(buffer.len(), GPT_HEADER_SIZE as usize);
+ }
+
+ #[test]
+ fn partition_entry_size() {
+ let mut buffer = vec![];
+ GptPartitionEntry::default().write_bytes(&mut buffer).unwrap();
+
+ assert_eq!(buffer.len(), GPT_PARTITION_ENTRY_SIZE as usize);
+ }
+}
diff --git a/virtualizationservice/src/main.rs b/virtualizationservice/src/main.rs
index a68e5eb..43b5fe4 100644
--- a/virtualizationservice/src/main.rs
+++ b/virtualizationservice/src/main.rs
@@ -17,6 +17,7 @@
mod aidl;
mod composite;
mod crosvm;
+mod gpt;
use crate::aidl::{VirtualizationService, BINDER_SERVICE_IDENTIFIER};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::BnVirtualizationService;