| # Android heap profiling daemon. go/heapprofd. |
| # |
| # On user builds, this daemon is responsible for receiving the initial |
| # profiling configuration, finding matching target processes (if profiling by |
| # process name), and sending the activation signal to them (+ setting system |
| # properties for new processes to start profiling from startup). When profiling |
| # is triggered in a process, it spawns a private heapprofd subprocess (in its |
| # own SELinux domain), which will exclusively handle profiling of its parent. |
| # |
| # On debug builds, this central daemon performs profiling for all target |
| # processes (which talk directly to this daemon). |
| type heapprofd_exec, exec_type, file_type, system_file_type; |
| type heapprofd_tmpfs, file_type; |
| |
| init_daemon_domain(heapprofd) |
| tmpfs_domain(heapprofd) |
| |
| # Allow apps in other MLS contexts (for multi-user) to access |
| # shared memory buffers created by heapprofd. |
| typeattribute heapprofd_tmpfs mlstrustedobject; |
| |
| set_prop(heapprofd, heapprofd_prop); |
| |
| # Necessary for /proc/[pid]/cmdline access & sending signals. |
| typeattribute heapprofd mlstrustedsubject; |
| |
| # Allow sending signals to processes. This excludes SIGKILL, SIGSTOP and |
| # SIGCHLD, which are controlled by separate permissions. |
| allow heapprofd self:capability kill; |
| |
| # When scanning /proc/[pid]/cmdline to find matching processes for by-name |
| # profiling, only allowlisted domains will be allowed by SELinux. Avoid |
| # spamming logs with denials for entries that we can not access. |
| dontaudit heapprofd domain:dir { search open }; |
| |
| # Write trace data to the Perfetto traced daemon. This requires connecting to |
| # its producer socket and obtaining a (per-process) tmpfs fd. |
| perfetto_producer(heapprofd) |
| |
| # When handling profiling for all processes, heapprofd needs to read |
| # executables/libraries/etc to do stack unwinding. |
| userdebug_or_eng(` |
| r_dir_file(heapprofd, nativetest_data_file) |
| r_dir_file(heapprofd, system_file_type) |
| r_dir_file(heapprofd, apk_data_file) |
| r_dir_file(heapprofd, dalvikcache_data_file) |
| r_dir_file(heapprofd, vendor_file_type) |
| # Some dex files are not world-readable. |
| # We are still constrained by the SELinux rules above. |
| allow heapprofd self:global_capability_class_set dac_read_search; |
| |
| allow heapprofd proc_kpageflags:file r_file_perms; |
| ') |
| |
| # This is going to happen on user but is benign because central heapprofd |
| # does not actually need these permission. |
| # If the dac_read_search capability check is rejected, the kernel then tries |
| # to perform a dac_override capability check, so we need to dontaudit that |
| # as well. |
| dontaudit heapprofd self:global_capability_class_set { dac_read_search dac_override }; |
| |
| 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 }; |
| ') |