diff --git a/dex2oat.te b/dex2oat.te index abdacebe8..48daac3fe 100644 --- a/dex2oat.te +++ b/dex2oat.te @@ -22,7 +22,10 @@ allow dex2oat user_profile_data_file:file { getattr read lock }; ################## # Allow dex2oat to use file descriptors from otapreopt. -allow dex2oat otapreopt:fd use; +allow dex2oat postinstall_dexopt:fd use; + +allow dex2oat postinstall_file:dir getattr; + # 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; diff --git a/domain.te b/domain.te index b485c2775..8ff05a5a2 100644 --- a/domain.te +++ b/domain.te @@ -360,7 +360,7 @@ neverallow { -init # TODO: limit init to relabelfrom for files -zygote -installd - -otapreopt + -postinstall_dexopt -dex2oat } dalvikcache_data_file:file no_w_file_perms; @@ -368,7 +368,7 @@ neverallow { domain -init -installd - -otapreopt + -postinstall_dexopt -dex2oat -zygote } dalvikcache_data_file:dir no_w_dir_perms; diff --git a/file_contexts b/file_contexts index b3e4e93f3..75edcc9de 100644 --- a/file_contexts +++ b/file_contexts @@ -174,7 +174,7 @@ /system/bin/mediacodec u:object_r:mediacodec_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/otapreopt_chroot u:object_r:otapreopt_chroot_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 diff --git a/installd.te b/installd.te index f4ea424c3..0e640419f 100644 --- a/installd.te +++ b/installd.te @@ -73,7 +73,9 @@ domain_auto_trans(installd, profman_exec, profman) domain_auto_trans(installd, idmap_exec, idmap) # Run otapreopt in its own sandbox. -domain_auto_trans(installd, otapreopt_exec, otapreopt) +domain_auto_trans(installd, otapreopt_chroot_exec, otapreopt_chroot) +# otapreopt_chroot will transition into postinstall_dexopt, which will spawn a child. +allow installd postinstall_dexopt:process sigchld; # Upgrade from unlabeled userdata. # Just need enough to remove and/or relabel it. diff --git a/otapreopt.te b/otapreopt.te deleted file mode 100644 index 0eada985b..000000000 --- a/otapreopt.te +++ /dev/null @@ -1,41 +0,0 @@ -# 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. - -# Read app data (APKs) as input to dex2oat. -r_dir_file(otapreopt, apk_data_file) -# Access to app oat directory. -r_dir_file(otapreopt, dalvikcache_data_file) - -# 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; - -# Need to write .b files, which are dalvikcache_data_file, not ota_data_file. -# TODO: See whether we can apply ota_data_file? -allow otapreopt dalvikcache_data_file:dir { write add_name remove_name }; -allow otapreopt dalvikcache_data_file: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/otapreopt_chroot.te b/otapreopt_chroot.te new file mode 100644 index 000000000..b3f8807b0 --- /dev/null +++ b/otapreopt_chroot.te @@ -0,0 +1,14 @@ +# otapreopt_chroot executable +type otapreopt_chroot, domain; +type otapreopt_chroot_exec, exec_type, file_type; + +# Chroot preparation and execution. +# We need to create an unshared mount namespace, and then mount /data. +allow otapreopt_chroot postinstall_file:dir { search mounton }; +allow otapreopt_chroot self:capability { sys_admin sys_chroot }; + +# Allow to transition to postinstall_ota, to run otapreopt in its own sandbox. +domain_auto_trans(otapreopt_chroot, postinstall_file, postinstall_dexopt) + +# Allow otapreopt to use file descriptors from installd. +allow otapreopt_chroot installd:fd use; diff --git a/postinstall.te b/postinstall.te index 938fcd23f..5c261efe9 100644 --- a/postinstall.te +++ b/postinstall.te @@ -22,3 +22,14 @@ allow postinstall toolbox_exec:file rx_file_perms; # No domain other than update_engine should transition to postinstall, as it is # only meant to run during the update. neverallow { domain -update_engine } postinstall:process { transition dyntransition }; + +# +# For OTA dexopt. +# + +# Allow postinstall scripts to talk to the system server. +binder_use(postinstall) +binder_call(postinstall, system_server) + +# Need to talk to the otadexopt service. +allow postinstall otadexopt_service:service_manager find; \ No newline at end of file diff --git a/postinstall_dexopt.te b/postinstall_dexopt.te new file mode 100644 index 000000000..dbc76dfb5 --- /dev/null +++ b/postinstall_dexopt.te @@ -0,0 +1,57 @@ +# Domain for the otapreopt executable, running under postinstall_dexopt +# +# Note: otapreopt is a driver for dex2oat, and reuses parts of installd. As such, +# this is derived and adapted from installd.te. + +type postinstall_dexopt, domain; + +# init_daemon_domain(otapreopt) +allow postinstall_dexopt self:capability { chown dac_override fowner setgid setuid }; + +allow postinstall_dexopt postinstall_file:dir getattr; +allow postinstall_dexopt proc:file { getattr open read }; +allow postinstall_dexopt tmpfs:file read; + +# Note: /data/ota is created by init (see system/core/rootdir/init.rc) to avoid giving access +# here and having to relabel the directory. + +# Read app data (APKs) as input to dex2oat. +r_dir_file(postinstall_dexopt, apk_data_file) +# Access to app oat directory. +r_dir_file(postinstall_dexopt, dalvikcache_data_file) + +# Read profile data. +allow postinstall_dexopt user_profile_data_file:dir { getattr search }; +allow postinstall_dexopt user_profile_data_file:file r_file_perms; + +# Write to /data/ota(/*). Create symlinks in /data/ota(/*) +allow postinstall_dexopt ota_data_file:dir create_dir_perms; +allow postinstall_dexopt ota_data_file:file create_file_perms; +allow postinstall_dexopt ota_data_file:lnk_file create_file_perms; + +# Need to write .b files, which are dalvikcache_data_file, not ota_data_file. +# TODO: See whether we can apply ota_data_file? +allow postinstall_dexopt dalvikcache_data_file:dir rw_dir_perms; +allow postinstall_dexopt dalvikcache_data_file:file create_file_perms; + +# Allow labeling of files under /data/app/com.example/oat/ +# TODO: Restrict to .b suffix? +allow postinstall_dexopt dalvikcache_data_file:dir relabelto; +allow postinstall_dexopt dalvikcache_data_file:file { relabelto link }; + +allow postinstall_dexopt selinuxfs:dir r_dir_perms; + +# Check validity of SELinux context before use. +selinux_check_context(postinstall_dexopt) +selinux_check_access(postinstall_dexopt) + +# Run dex2oat/patchoat in its own sandbox. +# We have to manually transition, as we don't have an entrypoint. +domain_auto_trans(postinstall_dexopt, postinstall_file, dex2oat) + +# installd wants to know about our child. +allow postinstall_dexopt installd:process sigchld; + +# Allow otapreopt to use file descriptors from otapreopt_chroot. +# TODO: Probably we can actually close file descriptors... +allow postinstall_dexopt otapreopt_chroot:fd use; diff --git a/system_server.te b/system_server.te index 3fb6c2ad0..8760182d1 100644 --- a/system_server.te +++ b/system_server.te @@ -503,6 +503,15 @@ allow system_server media_rw_data_file:dir search; # Allow invoking tools like "timeout" allow system_server toolbox_exec:file rx_file_perms; +# Postinstall +# +# For OTA dexopt, allow calls coming from postinstall. +binder_call(system_server, postinstall) + +allow system_server postinstall:fifo_file write; +allow system_server update_engine:fd use; +allow system_server update_engine:fifo_file write; + ### ### Neverallow rules ###