Add tradeinmode sepolicy.
This allows adbd_tradeinmode to run a wrapper to execute am/content.
This defines a transition from adbd_tradeinmode to tradeinmode, but no
transition from tradeinmode to zygote/am, similar to how "adb shell am"
would work.
There are still denials here, but they don't appear to be critical to
am/content working. These denials would be fixed by:
allow tradeinmode dalvikcache_data_file:dir search;
allow tradeinmode platform_app:binder call;
allow tradeinmode self:anon_inode { create ioctl };
allow tradeinmode tmpfs:file { execute map read write };
The set of denial logs is roughly:
auditd : type=1400 audit(0.0:45): avc: denied { write } for comm="main" name="memfd:jit-cache" dev="tmpfs" ino=3547 scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tmpfs:s0 tclass=file permissive=0
auditd : type=1400 audit(0.0:46): avc: denied { search } for comm="main" name="dalvik-cache" dev="dm-56" ino=114 scontext=u:r:tradeinmode:s0 tcontext=u:object_r:dalvikcache_data_file:s0 tclass=dir permissive=0
auditd : type=1400 audit(0.0:50): avc: denied { create } for comm="app_process" anonclass=[userfaultfd] scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tradeinmode:s0 tclass=anon_inode permissive=0
app_process: type=1400 audit(0.0:50): avc: denied { create } for anonclass=[userfaultfd] scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tradeinmode:s0 tclass=anon_inode permissive=0
auditd : type=1400 audit(0.0:51): avc: denied { create } for comm="app_process" anonclass=[userfaultfd] scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tradeinmode:s0 tclass=anon_inode permissive=0
app_process: type=1400 audit(0.0:51): avc: denied { create } for anonclass=[userfaultfd] scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tradeinmode:s0 tclass=anon_inode permissive=0
auditd : type=1400 audit(0.0:52): avc: denied { map } for comm="main" path=2F6D656D66643A6A69742D6361636865202864656C6574656429 dev="tmpfs" ino=1332 scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tmpfs:s0 tclass=file permissive=0
auditd : type=1400 audit(0.0:19): avc: denied { getattr } for comm="sh" path="/system/bin/tradeinmode" dev="dm-7" ino=547 scontext=u:r:shell:s0 tcontext=u:object_r:tradeinmode_exec:s0 tclass=file permissive=0
auditd : type=1400 audit(0.0:20): avc: denied { getattr } for comm="sh" path="/system/bin/tradeinmode" dev="dm-7" ino=547 scontext=u:r:shell:s0 tcontext=u:object_r:tradeinmode_exec:s0 tclass=file permissive=0
auditd : type=1400 audit(0.0:21): avc: denied { getattr } for comm="sh" path="/system/bin/tradeinmode" dev="dm-7" ino=547 scontext=u:r:shell:s0 tcontext=u:object_r:tradeinmode_exec:s0 tclass=file permissive=0
auditd : type=1400 audit(0.0:98): avc: denied { read } for comm="main" path=2F6D656D66643A6A69742D6361636865202864656C6574656429 dev="tmpfs" ino=1372 scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tmpfs:s0 tclass=file permissive=0
auditd : type=1400 audit(0.0:99): avc: denied { call } for comm="main" scontext=u:r:tradeinmode:s0 tcontext=u:r:platform_app:s0:c512,c768 tclass=binder permissive=0
auditd : type=1400 audit(0.0:59): avc: denied { execute } for comm="main" path=2F6D656D66643A6A69742D6361636865202864656C6574656429 dev="tmpfs" ino=6556 scontext=u:r:tradeinmode:s0 tcontext=u:object_r:tmpfs:s0 tclass=file permissive=0
Test: manual test
Bug: 307713521
Change-Id: I5ece68f6ec82d46fc040911c2b42aa435c71787d
diff --git a/contexts/plat_file_contexts_test b/contexts/plat_file_contexts_test
index e990aba..936a524 100644
--- a/contexts/plat_file_contexts_test
+++ b/contexts/plat_file_contexts_test
@@ -410,6 +410,7 @@
/system/bin/traced_perf traced_perf_exec
/system/bin/traced_probes traced_probes_exec
/system/bin/traced_relay traced_exec
+/system/bin/tradeinmode tradeinmode_exec
/system/bin/heapprofd heapprofd_exec
/system/bin/uncrypt uncrypt_exec
/system/bin/update_verifier update_verifier_exec
diff --git a/private/adbd_tradeinmode.te b/private/adbd_tradeinmode.te
index 2eae26a..42fdec4 100644
--- a/private/adbd_tradeinmode.te
+++ b/private/adbd_tradeinmode.te
@@ -4,6 +4,9 @@
# Create and use network sockets.
net_domain(adbd_tradeinmode)
+# Run /system/bin/tradeinmode
+domain_auto_trans(adbd_tradeinmode, tradeinmode_exec, tradeinmode)
+
# Baseline rules to make adbd work after setcon().
allow adbd_tradeinmode adbd:unix_stream_socket {
rw_socket_perms_no_ioctl
diff --git a/private/domain.te b/private/domain.te
index ceab2dd..75bcdf9 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -1364,10 +1364,17 @@
} shell:process { transition dyntransition };
# Only domains spawned from zygote, runas and simpleperf_app_runner may have
-# the appdomain attribute. simpleperf is excluded as a domain transitioned to
-# when running an app-scoped profiling session.
+# the appdomain attribute.
+#
+# simpleperf is excluded as a domain transitioned to when running an app-scoped
+# profiling session.
+#
+# tradeinmode is excluded; it is only run when adbd is in trade-in mode,
+# transitioned from the limited adbd_tradeinmode context. It is a wrapper
+# around "am" to avoid exposing the shell context when adbd is in trade-in
+# mode.
neverallow { domain -simpleperf_app_runner -runas -app_zygote -webview_zygote -zygote } {
- appdomain -shell -simpleperf userdebug_or_eng(`-su')
+ appdomain -shell -simpleperf userdebug_or_eng(`-su') -tradeinmode
}:process { transition dyntransition };
# Minimize read access to shell- or app-writable symlinks.
diff --git a/private/file_contexts b/private/file_contexts
index 016e3e2..f837b70 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -410,7 +410,7 @@
/system/bin/uprobestats u:object_r:uprobestats_exec:s0
/system/bin/bert_collector u:object_r:bert_collector_exec:s0
/system/bin/linux_vm_setup u:object_r:linux_vm_setup_exec:s0
-
+/system/bin/tradeinmode u:object_r:tradeinmode_exec:s0
#############################
# Vendor files
diff --git a/private/system_server.te b/private/system_server.te
index 063c2ed..e84175b 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -1447,6 +1447,9 @@
# Allow system server to read /apex/apex-info-list.xml
allow system_server apex_info_file:file r_file_perms;
+# Allow system_server to communicate with tradeinmode.
+binder_call(system_server, tradeinmode)
+
# Allow system server to communicate to system-suspend's control interface
allow system_server system_suspend_control_internal_service:service_manager find;
allow system_server system_suspend_control_service:service_manager find;
diff --git a/private/tradeinmode.te b/private/tradeinmode.te
new file mode 100644
index 0000000..05315a4
--- /dev/null
+++ b/private/tradeinmode.te
@@ -0,0 +1,26 @@
+### trade-in mode
+
+type tradeinmode, domain, coredomain;
+type tradeinmode_exec, exec_type, file_type, system_file_type;
+
+allow tradeinmode adbd_tradeinmode:fd use;
+
+allow tradeinmode adbd_tradeinmode:unix_stream_socket { read write ioctl };
+allow tradeinmode devpts:chr_file rw_file_perms;
+
+# Allow executing am/content without a domain transition.
+allow tradeinmode system_file:file rx_file_perms;
+allow tradeinmode zygote_exec:file rx_file_perms;
+allow tradeinmode apex_info_file:file r_file_perms;
+
+allow tradeinmode activity_service:service_manager find;
+
+get_prop(tradeinmode, odsign_prop)
+get_prop(tradeinmode, build_attestation_prop)
+
+# Needed to start activities through "am".
+binder_call(tradeinmode, system_server)
+binder_call(tradeinmode, servicemanager)
+
+# Needed to run "content".
+binder_call(tradeinmode, platform_app)