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)