perf_event: rules for system and simpleperf domain

This patch adds the necessary rules to support the existing usage of
perf_event_open by the system partition, which almost exclusively
concerns the simpleperf profiler. A new domain is introduced for some
(but not all) executions of the system image simpleperf. The following
configurations are supported:
* shell -> shell process (no domain transition)
* shell -> debuggable app (through shell -> runas -> runas_app)
* shell -> profileable app (through shell -> simpleperf_app_runner ->
                            untrusted_app -> simpleperf)
* debuggable/profile app -> self (through untrusted_app -> simpleperf)

simpleperf_app_runner still enters the untrusted_app domain immediately
before exec to properly inherit the categories related to MLS. My
understanding is that a direct transition would require modifying
external/selinux and seapp_contexts as with "fromRunAs", which seems
unnecessarily complex for this case.

runas_app can still run side-loaded binaries and use perf_event_open,
but it checks that the target app is exactly "debuggable"
(profileability is insufficient).

system-wide profiling is effectively constrained to "su" on debug
builds.

See go/perf-event-open-security for a more detailed explanation of the
scenarios covered here.

Tested: "atest CtsSimpleperfTestCases" on crosshatch-user/userdebug
Tested: manual simpleperf invocations on crosshatch-userdebug
Bug: 137092007
Change-Id: I2100929bae6d81f336f72eff4235fd5a78b94066
diff --git a/private/runas_app.te b/private/runas_app.te
index e6fd953..c1b354a 100644
--- a/private/runas_app.te
+++ b/private/runas_app.te
@@ -16,3 +16,17 @@
 # Allow lldb/ndk-gdb/simpleperf to ptrace attach to debuggable app processes.
 allow runas_app untrusted_app_all:process { ptrace signal sigstop };
 allow runas_app untrusted_app_all:unix_stream_socket connectto;
+
+# Allow executing system image simpleperf without a domain transition.
+allow runas_app simpleperf_exec:file rx_file_perms;
+
+# Suppress denial logspam when simpleperf is trying to find a matching process
+# by scanning /proc/<pid>/cmdline files. The /proc/<pid> directories are within
+# the same domain as their respective process, most of which this domain is not
+# allowed to see.
+dontaudit runas_app domain:dir search;
+
+# Allow runas_app to call perf_event_open for profiling debuggable app
+# processes, but not the whole system.
+allow runas_app self:perf_event { open read write kernel };
+neverallow runas_app self:perf_event ~{ open read write kernel };