Selinux: introduce policy for OTA preopt
Add permissions to dex2oat, introduce otapreopt binary and otadexopt
service.
Bug: 25612095
Change-Id: I80fcba2785e80b2931d7d82bb07474f6cd0099f7
diff --git a/dex2oat.te b/dex2oat.te
index 42abb55..4252b88 100644
--- a/dex2oat.te
+++ b/dex2oat.te
@@ -3,7 +3,8 @@
type dex2oat_exec, exec_type, file_type;
allow dex2oat dalvikcache_data_file:file write;
-# Read symlinks in /data/dalvik-cache
+# Read symlinks in /data/dalvik-cache. This is required for PIC mode boot images, where
+# the oat file is symlinked to the original file in /system.
allow dex2oat dalvikcache_data_file:lnk_file read;
allow dex2oat installd:fd use;
@@ -16,4 +17,27 @@
allow dex2oat apk_tmp_file:file read;
allow dex2oat app_data_file:file {read write lock};
+##################
+# A/B OTA Dexopt #
+##################
+
+# Allow dex2oat to use file descriptors from otapreopt.
+allow dex2oat otapreopt:fd use;
+# Allow dex2oat access to files in /data/ota.
+allow dex2oat ota_data_file:dir ra_dir_perms;
+allow dex2oat ota_data_file:file r_file_perms;
+
+# Read symlinks in /data/ota/dalvik-cache. This is required for PIC mode boot images, where
+# the oat file is symlinked to the original file in /system.
+allow dex2oat ota_data_file:lnk_file read;
+
+# It would be nice to tie this down, but currently, because of how images are written, we can't
+# pass file descriptors for the preopted boot image to dex2oat. So dex2oat needs to be able to
+# create them itself (and make them world-readable).
+allow dex2oat ota_data_file:file { create w_file_perms setattr };
+
+##############
+# Neverallow #
+##############
+
neverallow dex2oat app_data_file:notdevfile_class_set open;
diff --git a/domain.te b/domain.te
index 7081428..7ad4e46 100644
--- a/domain.te
+++ b/domain.te
@@ -341,6 +341,7 @@
-init # TODO: limit init to relabelfrom for files
-zygote
-installd
+ -otapreopt
-dex2oat
} dalvikcache_data_file:file no_w_file_perms;
@@ -348,6 +349,7 @@
domain
-init
-installd
+ -otapreopt
-dex2oat
-zygote
} dalvikcache_data_file:dir no_w_dir_perms;
diff --git a/file.te b/file.te
index 25c4c06..88d997c 100644
--- a/file.te
+++ b/file.te
@@ -82,6 +82,8 @@
type apk_private_tmp_file, file_type, data_file_type, mlstrustedobject;
# /data/dalvik-cache
type dalvikcache_data_file, file_type, data_file_type;
+# /data/ota
+type ota_data_file, file_type, data_file_type;
# /data/resource-cache
type resourcecache_data_file, file_type, data_file_type;
# /data/local - writable by shell
diff --git a/file_contexts b/file_contexts
index f292780..1195ebd 100644
--- a/file_contexts
+++ b/file_contexts
@@ -170,6 +170,7 @@
/system/bin/mediaextractor u:object_r:mediaextractor_exec:s0
/system/bin/mdnsd u:object_r:mdnsd_exec:s0
/system/bin/installd u:object_r:installd_exec:s0
+/system/bin/otapreopt u:object_r:otapreopt_exec:s0
/system/bin/keystore u:object_r:keystore_exec:s0
/system/bin/fingerprintd u:object_r:fingerprintd_exec:s0
/system/bin/gatekeeperd u:object_r:gatekeeperd_exec:s0
@@ -237,6 +238,7 @@
/data/gps(/.*)? u:object_r:gps_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/adb(/.*)? u:object_r:adb_data_file:s0
/data/anr(/.*)? u:object_r:anr_data_file:s0
/data/app(/.*)? u:object_r:apk_data_file:s0
diff --git a/installd.te b/installd.te
index 379e074..f685a48 100644
--- a/installd.te
+++ b/installd.te
@@ -69,6 +69,9 @@
# Run idmap in its own sandbox.
domain_auto_trans(installd, idmap_exec, idmap)
+# Run otapreopt in its own sandbox.
+domain_auto_trans(installd, otapreopt_exec, otapreopt)
+
# Upgrade from unlabeled userdata.
# Just need enough to remove and/or relabel it.
allow installd unlabeled:dir { getattr search relabelfrom rw_dir_perms rmdir };
diff --git a/otapreopt.te b/otapreopt.te
new file mode 100644
index 0000000..bb90eaf
--- /dev/null
+++ b/otapreopt.te
@@ -0,0 +1,31 @@
+# otapreopt executable
+type otapreopt, domain, mlstrustedsubject;
+type otapreopt_exec, exec_type, file_type;
+
+init_daemon_domain(otapreopt)
+allow otapreopt self:capability { chown dac_override fowner fsetid setgid setuid };
+
+# Note: /data/ota is created by init (see system/core/rootdir/init.rc) to avoid giving access
+# here and having to relabel the directory.
+
+# Write to /data/ota(/*). Create symlinks in /data/ota(/*)
+allow otapreopt ota_data_file:dir create_dir_perms;
+allow otapreopt ota_data_file:file create_file_perms;
+allow otapreopt ota_data_file:lnk_file create_file_perms;
+
+# Allow labeling of files under /data/app/com.example/oat/
+# TODO: Restrict to .b suffix?
+allow otapreopt dalvikcache_data_file:dir relabelto;
+allow otapreopt dalvikcache_data_file:file { relabelto link };
+
+allow otapreopt selinuxfs:dir r_dir_perms;
+
+# Check validity of SELinux context before use.
+selinux_check_context(otapreopt)
+selinux_check_access(otapreopt)
+
+# Run dex2oat in its own sandbox.
+domain_auto_trans(otapreopt, dex2oat_exec, dex2oat)
+
+# Allow otapreopt to use file descriptors from installd.
+allow otapreopt installd:fd use;
diff --git a/service.te b/service.te
index 7e004b4..45f1c87 100644
--- a/service.te
+++ b/service.te
@@ -71,6 +71,7 @@
type network_management_service, app_api_service, system_server_service, service_manager_type;
type network_score_service, system_api_service, system_server_service, service_manager_type;
type notification_service, app_api_service, system_server_service, service_manager_type;
+type otadexopt_service, system_server_service, service_manager_type;
type package_service, app_api_service, system_server_service, service_manager_type;
type permission_service, app_api_service, system_server_service, service_manager_type;
type persistent_data_block_service, system_api_service, system_server_service, service_manager_type;
diff --git a/service_contexts b/service_contexts
index 1f3e572..747369e 100644
--- a/service_contexts
+++ b/service_contexts
@@ -84,6 +84,7 @@
network_score u:object_r:network_score_service:s0
nfc u:object_r:nfc_service:s0
notification u:object_r:notification_service:s0
+otadexopt u:object_r:otadexopt_service:s0
package u:object_r:package_service:s0
permission u:object_r:permission_service:s0
persistent_data_block u:object_r:persistent_data_block_service:s0