Add userdebug selinux config for heapprofd.

Test: m
Test: flash sailfish
Test: profile system_server

Change-Id: I577793af655146ee91be86bb286fcf9d6e6d081d
diff --git a/private/heapprofd.te b/private/heapprofd.te
index ada66d5..79249b3 100644
--- a/private/heapprofd.te
+++ b/private/heapprofd.te
@@ -1,5 +1,40 @@
 # Android Heap Profiler Daemon go/heapprofd
-type heapprofd, domain, coredomain;
 type heapprofd_exec, exec_type, file_type, system_file_type;
 
 init_daemon_domain(heapprofd)
+
+userdebug_or_eng(`
+  # Allow to send signal to processes.
+  # This excludes SIGKILL, SIGSTOP and SIGCHLD,
+  # which are controlled by separate permissions.
+  allow heapprofd self:capability kill;
+
+  # Executables and libraries.
+  # These are needed to read the ELF binary data needed for unwinding.
+  allow heapprofd system_file:file r_file_perms;
+  allow heapprofd apk_data_file:file r_file_perms;
+  allow heapprofd dalvikcache_data_file:file r_file_perms;
+  allow heapprofd vendor_file_type:file r_file_perms;
+')
+
+# Write trace data to the Perfetto traced damon. This requires connecting to its
+# producer socket and obtaining a (per-process) tmpfs fd.
+allow heapprofd traced:fd use;
+allow heapprofd traced_tmpfs:file { read write getattr map };
+unix_socket_connect(heapprofd, traced_producer, traced)
+
+never_profile_heap(`{
+  bpfloader
+  init
+  kernel
+  keystore
+  llkd
+  logd
+  ueventd
+  vendor_init
+  vold
+}')
+
+full_treble_only(`
+  neverallow heapprofd vendor_file:file { no_w_file_perms no_x_file_perms };
+')
diff --git a/private/system_server.te b/private/system_server.te
index 7c9e2f2..01f0211 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -5,6 +5,7 @@
 
 typeattribute system_server coredomain;
 typeattribute system_server mlstrustedsubject;
+can_profile_heap(system_server)
 
 # Define a type for tmpfs-backed ashmem regions.
 tmpfs_domain(system_server)
diff --git a/public/domain.te b/public/domain.te
index b17893b..0a47bc6 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -995,6 +995,7 @@
         -init
         -installd
         userdebug_or_eng(`-perfprofd')
+        userdebug_or_eng(`-heapprofd')
         -postinstall_dexopt
         -system_server
     } vendor_app_file:dir { open read getattr search };
@@ -1009,6 +1010,7 @@
         -init
         -installd
         userdebug_or_eng(`-perfprofd')
+        userdebug_or_eng(`-heapprofd')
         -postinstall_dexopt
         -system_server
         -mediaserver
@@ -1026,6 +1028,7 @@
         -system_server
         -webview_zygote
         -zygote
+        userdebug_or_eng(`-heapprofd')
     } vendor_overlay_file:dir { getattr open read search };
 ')
 
@@ -1039,6 +1042,7 @@
         -system_server
         -webview_zygote
         -zygote
+        userdebug_or_eng(`-heapprofd')
     } vendor_overlay_file:file r_file_perms;
 ')
 
@@ -1109,6 +1113,7 @@
     -init # starts vendor executables
     -kernel # loads /vendor/firmware
     userdebug_or_eng(`-perfprofd')
+    userdebug_or_eng(`-heapprofd')
     -shell
     -system_executes_vendor_violators
     -ueventd # reads /vendor/ueventd.rc
@@ -1446,6 +1451,7 @@
     -init
     -kernel
     -perfprofd
+    -heapprofd
     -ueventd
   } vendor_file:file { no_w_file_perms no_x_file_perms open };
 ')
diff --git a/public/heapprofd.te b/public/heapprofd.te
new file mode 100644
index 0000000..7ceb23f
--- /dev/null
+++ b/public/heapprofd.te
@@ -0,0 +1 @@
+type heapprofd, domain, coredomain;
diff --git a/public/te_macros b/public/te_macros
index e756f36..c70e7db 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -643,3 +643,35 @@
     neverallow { domain -$1_client -$1_server } $2:hwservice_manager find;
   ')
 ')
+
+###################################
+# can_profile_heap(domain)
+# never_profile_heap(domain)
+#
+# Opt in our out of heap profiling.
+# This will allow a heap profiling daemon to read this
+# process' address space in order to support unwinding.
+#
+define(`can_profile_heap', `
+  userdebug_or_eng(`
+    # RT signal for client initialization.
+    allow heapprofd $1:process signal;
+    # Connect to heapprofd service.
+    unix_socket_connect($1, heapprofd, heapprofd)
+    # To receive file descriptor.
+    allow heapprofd $1:fd use;
+
+    # To read from the received file descriptors.
+    # /proc/[pid]/maps and /proc/[pid]/mem have the same SELinux label as the
+    # process they relate to.
+    allow heapprofd $1:file r_file_perms;
+    # This is needed to search the /proc/[pid] directory.
+    allow heapprofd $1:dir r_dir_perms;
+    allow heapprofd $1:process signal;
+  ')
+')
+
+define(`never_profile_heap', `
+  neverallow heapprofd $1:file read;
+  neverallow heapprofd $1:process signal;
+')