From 47ebae1a7a209df9d5b38c5028b8544f64da703d Mon Sep 17 00:00:00 2001
From: Andreas Gampe <agampe@google.com>
Date: Wed, 2 Dec 2015 21:23:30 -0800
Subject: [PATCH] Selinux: introduce policy for OTA preopt

Add permissions to dex2oat, introduce otapreopt binary and otadexopt
service.

Bug: 25612095
Change-Id: I80fcba2785e80b2931d7d82bb07474f6cd0099f7
---
 dex2oat.te       | 26 +++++++++++++++++++++++++-
 domain.te        |  2 ++
 file.te          |  2 ++
 file_contexts    |  2 ++
 installd.te      |  3 +++
 otapreopt.te     | 31 +++++++++++++++++++++++++++++++
 service.te       |  1 +
 service_contexts |  1 +
 8 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 otapreopt.te

diff --git a/dex2oat.te b/dex2oat.te
index 42abb55d7..4252b88fa 100644
--- a/dex2oat.te
+++ b/dex2oat.te
@@ -3,7 +3,8 @@ type dex2oat, domain, mlstrustedsubject, domain_deprecated;
 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 oemfs:file read;
 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 708142823..7ad4e4649 100644
--- a/domain.te
+++ b/domain.te
@@ -341,6 +341,7 @@ neverallow {
   -init # TODO: limit init to relabelfrom for files
   -zygote
   -installd
+  -otapreopt
   -dex2oat
 } dalvikcache_data_file:file no_w_file_perms;
 
@@ -348,6 +349,7 @@ neverallow {
   domain
   -init
   -installd
+  -otapreopt
   -dex2oat
   -zygote
 } dalvikcache_data_file:dir no_w_dir_perms;
diff --git a/file.te b/file.te
index 25c4c0660..88d997c9f 100644
--- a/file.te
+++ b/file.te
@@ -82,6 +82,8 @@ type apk_private_data_file, file_type, data_file_type;
 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 f2927801a..1195ebdd8 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 379e0745c..f685a4883 100644
--- a/installd.te
+++ b/installd.te
@@ -69,6 +69,9 @@ domain_auto_trans(installd, dex2oat_exec, dex2oat)
 # 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 000000000..bb90eafcd
--- /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 7e004b420..45f1c877c 100644
--- a/service.te
+++ b/service.te
@@ -71,6 +71,7 @@ type netstats_service, app_api_service, system_server_service, service_manager_t
 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 1f3e572ec..747369ef7 100644
--- a/service_contexts
+++ b/service_contexts
@@ -84,6 +84,7 @@ network_management                        u:object_r:network_management_service:
 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
-- 
GitLab