Transient SELinux domain for system_server JIT
Create a transient SELinux domain where system_server can perform
certain JIT setup. The idea is that system_server will start in the
system_server_startup domain, setup certain JIT pages, then perform a
one-way transition into the system_server domain. From that point,
further JITing operations are disallowed.
Bug: 62356545
Test: device boots, no permission errors
Change-Id: Ic55b2cc5aba420ebcf62736622e08881a4779004
diff --git a/private/domain.te b/private/domain.te
index 7945d89..8e3c4e6 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -175,3 +175,38 @@
-init
-installd
} { privapp_data_file app_data_file }:dir_file_class_set { relabelfrom relabelto };
+
+neverallow {
+ domain
+ -appdomain # for oemfs
+ -bootanim # for oemfs
+ -recovery # for /tmp/update_binary in tmpfs
+} { fs_type -rootfs }:file execute;
+
+#
+# Assert that, to the extent possible, we're not loading executable content from
+# outside the rootfs or /system partition except for a few whitelisted domains.
+# Executable files loaded from /data is a persistence vector
+# we want to avoid. See
+# https://bugs.chromium.org/p/project-zero/issues/detail?id=955 for example.
+#
+neverallow {
+ domain
+ -appdomain
+ with_asan(`-asan_extract')
+ -shell
+ userdebug_or_eng(`-su')
+ -system_server_startup # for memfd backed executable regions
+ -webview_zygote
+ -zygote
+ userdebug_or_eng(`-mediaextractor')
+ userdebug_or_eng(`-mediaswcodec')
+} {
+ file_type
+ -system_file_type
+ -system_lib_file
+ -system_linker_exec
+ -vendor_file_type
+ -exec_type
+ -postinstall_file
+}:file execute;
diff --git a/private/seapp_contexts b/private/seapp_contexts
index 418150e..d0cf2a5 100644
--- a/private/seapp_contexts
+++ b/private/seapp_contexts
@@ -98,7 +98,8 @@
# Ephemeral Apps must run in the ephemeral_app domain
neverallow isEphemeralApp=true domain=((?!ephemeral_app).)*
-isSystemServer=true domain=system_server
+isSystemServer=true domain=system_server_startup
+
user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
user=system seinfo=platform domain=system_app type=system_app_data_file
user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
diff --git a/private/system_server.te b/private/system_server.te
index 42a89d4..506378e 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -912,6 +912,11 @@
# TODO: deal with tmpfs_domain pub/priv split properly
neverallow system_server system_server_tmpfs:file execute;
+# Resources handed off by system_server_startup
+allow system_server system_server_startup:fd use;
+allow system_server system_server_startup_tmpfs:file { read write map };
+allow system_server system_server_startup:unix_dgram_socket write;
+
# dexoptanalyzer is currently used only for secondary dex files which
# system_server should never access.
neverallow system_server dexoptanalyzer_exec:file no_x_file_perms;
diff --git a/private/system_server_startup.te b/private/system_server_startup.te
new file mode 100644
index 0000000..4bd10c8
--- /dev/null
+++ b/private/system_server_startup.te
@@ -0,0 +1,12 @@
+type system_server_startup, domain, coredomain;
+
+tmpfs_domain(system_server_startup)
+
+# Create JIT memory
+allow system_server_startup self:process execmem;
+allow system_server_startup system_server_startup_tmpfs:file { execute read write open map };
+
+# Allow system_server_startup to run setcon() and enter the
+# system_server domain
+allow system_server_startup self:process setcurrent;
+allow system_server_startup system_server:process dyntransition;
diff --git a/private/zygote.te b/private/zygote.te
index 0e21d51..491f079 100644
--- a/private/zygote.te
+++ b/private/zygote.te
@@ -14,7 +14,7 @@
# Switch SELinux context to app domains.
allow zygote self:process setcurrent;
-allow zygote system_server:process dyntransition;
+allow zygote system_server_startup:process dyntransition;
allow zygote appdomain:process dyntransition;
allow zygote webview_zygote:process dyntransition;
@@ -132,8 +132,12 @@
# written on appdomain are applied to all app processes.
# This is achieved by ensuring that it is impossible for zygote to
# setcon (dyntransition) to any types other than those associated
-# with appdomain plus system_server and webview_zygote.
-neverallow zygote ~{ appdomain system_server webview_zygote }:process dyntransition;
+# with appdomain plus system_server_startup and webview_zygote.
+neverallow zygote ~{
+ appdomain
+ system_server_startup
+ webview_zygote
+}:process dyntransition;
# Zygote should never execute anything from /data except for /data/dalvik-cache files.
neverallow zygote {
diff --git a/public/domain.te b/public/domain.te
index dcd12b1..89f1635 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -476,40 +476,6 @@
# this capability, including device-specific domains.
neverallow { domain -kernel -init -recovery -vold -zygote -update_engine -otapreopt_chroot -apexd } { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };
-#
-# Assert that, to the extent possible, we're not loading executable content from
-# outside the rootfs or /system partition except for a few whitelisted domains.
-# Executable files loaded from /data is a persistence vector
-# we want to avoid. See
-# https://bugs.chromium.org/p/project-zero/issues/detail?id=955 for example.
-#
-neverallow {
- domain
- -appdomain
- with_asan(`-asan_extract')
- -shell
- userdebug_or_eng(`-su')
- -webview_zygote
- -zygote
- userdebug_or_eng(`-mediaextractor')
- userdebug_or_eng(`-mediaswcodec')
-} {
- file_type
- -system_file_type
- -system_lib_file
- -system_linker_exec
- -vendor_file_type
- -exec_type
- -postinstall_file
-}:file execute;
-
-neverallow {
- domain
- -appdomain # for oemfs
- -bootanim # for oemfs
- -recovery # for /tmp/update_binary in tmpfs
-} { fs_type -rootfs }:file execute;
-
# Files from cache should never be executed
neverallow domain { cache_file cache_backup_file cache_private_backup_file cache_recovery_file }:file execute;