From 1a9f4f7a7a23afe61693d726eb72f2074eb37bbd Mon Sep 17 00:00:00 2001 From: Primiano Tucci Date: Wed, 24 Jan 2018 16:07:09 +0000 Subject: [PATCH] SELinux policies for Perfetto cmdline client (/system/bin/perfetto) Instead of having statsd linking the perfetto client library and talk directly to its socket, we let just statsd exec() the /system/bin/perfetto cmdline client. There are two reasons for this: 1) Simplify the interaction between statsd and perfetto, reduce dependencies, binary size bloat and isolate faults. 2) The cmdline client also takes care of handing the trace to Dropbox. This allows to expose the binder interaction surface to the short-lived cmdline client and avoid to grant binder access to the perfetto traced daemon. This cmdline client will be used by: - statsd - the shell user (for our UI and Studio) Bug: 70942310 Change-Id: I8cdde181481ad0a1a5cae5937ac446cedac54a1f --- private/compat/26.0/26.0.ignore.cil | 4 ++ private/file.te | 3 ++ private/file_contexts | 2 + private/perfetto.te | 60 +++++++++++++++++++++++++++++ private/shell.te | 9 +++++ private/statsd.te | 7 +++- private/su.te | 3 ++ private/system_server.te | 6 ++- 8 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 private/perfetto.te diff --git a/private/compat/26.0/26.0.ignore.cil b/private/compat/26.0/26.0.ignore.cil index ca2635759..2b0a3fb9e 100644 --- a/private/compat/26.0/26.0.ignore.cil +++ b/private/compat/26.0/26.0.ignore.cil @@ -59,6 +59,10 @@ network_watchlist_data_file network_watchlist_service package_native_service + perfetto + perfetto_exec + perfetto_tmpfs + perfetto_traces_data_file perfprofd_service property_info slice_service diff --git a/private/file.te b/private/file.te index 5ff77680e..0dcf25461 100644 --- a/private/file.te +++ b/private/file.te @@ -9,3 +9,6 @@ type storaged_data_file, file_type, data_file_type, core_data_file_type; # /data/misc/wmtrace for wm traces type wm_trace_data_file, file_type, data_file_type, core_data_file_type; + +# /data/misc/perfetto-traces for perfetto traces +type perfetto_traces_data_file, file_type, data_file_type, core_data_file_type; diff --git a/private/file_contexts b/private/file_contexts index 0afca24b2..80fa93d7a 100644 --- a/private/file_contexts +++ b/private/file_contexts @@ -246,6 +246,7 @@ /system/bin/usbd u:object_r:usbd_exec:s0 /system/bin/inputflinger u:object_r:inputflinger_exec:s0 /system/bin/logd u:object_r:logd_exec:s0 +/system/bin/perfetto u:object_r:perfetto_exec:s0 /system/bin/traced u:object_r:traced_exec:s0 /system/bin/traced_probes u:object_r:traced_probes_exec:s0 /system/bin/uncrypt u:object_r:uncrypt_exec:s0 @@ -391,6 +392,7 @@ /data/misc/media(/.*)? u:object_r:media_data_file:s0 /data/misc/net(/.*)? u:object_r:net_data_file:s0 /data/misc/network_watchlist(/.*)? u:object_r:network_watchlist_data_file:s0 +/data/misc/perfetto-traces(/.*)? u:object_r:perfetto_traces_data_file:s0 /data/misc/recovery(/.*)? u:object_r:recovery_data_file:s0 /data/misc/shared_relro(/.*)? u:object_r:shared_relro_file:s0 /data/misc/sms(/.*)? u:object_r:radio_data_file:s0 diff --git a/private/perfetto.te b/private/perfetto.te new file mode 100644 index 000000000..389fdf4f9 --- /dev/null +++ b/private/perfetto.te @@ -0,0 +1,60 @@ +# Perfetto command-line client. Can be used only from the domains that are +# explicitly whitelisted with a domain_auto_trans(X, perfetto_exec, perfetto). +# This command line client accesses the privileged socket of the traced +# daemon. + +type perfetto, domain, coredomain; +type perfetto_exec, exec_type, file_type; + +tmpfs_domain(perfetto); + +# Allow to access traced's privileged consumer socket. +unix_socket_connect(perfetto, traced_consumer, traced) + +# Allow to write and unlink traces into /data/misc/perfetto-traces. +allow perfetto perfetto_traces_data_file:dir rw_dir_perms; +allow perfetto perfetto_traces_data_file:file create_file_perms; + +# Allow to access binder to pass the traces to Dropbox. +binder_use(perfetto) +binder_call(perfetto, system_server) +allow perfetto dropbox_service:service_manager find; + +# Allow statsd and shell to pipe the trace config to perfetto on stdin and to +# print out on stdout/stderr. +allow perfetto statsd:fd use; +allow perfetto statsd:fifo_file { getattr read write }; +allow perfetto shell:fd use; +allow perfetto shell:fifo_file { getattr read write }; + +# Allow to communicate use, read and write over the adb connection. +allow perfetto adbd:fd use; +allow perfetto adbd:unix_stream_socket { read write }; + +# allow adbd to reap perfetto +allow perfetto adbd:process { sigchld }; + +# Allow to access /dev/pts when launched in an adb shell. +allow perfetto devpts:chr_file rw_file_perms; + +### +### Neverallow rules +### +### perfetto should NEVER do any of this + +# Disallow mapping executable memory (execstack and exec are already disallowed +# globally in domain.te). +neverallow perfetto self:process execmem; + +# Block device access. +neverallow perfetto dev_type:blk_file { read write }; + +# ptrace any other process +neverallow perfetto domain:process ptrace; + +# Disallows access to other /data files. +neverallow perfetto { data_file_type -system_data_file -zoneinfo_data_file -perfetto_traces_data_file }:dir *; +neverallow perfetto { system_data_file -perfetto_traces_data_file }:dir ~{ getattr search }; +neverallow perfetto zoneinfo_data_file:dir ~r_dir_perms; +neverallow perfetto { data_file_type -zoneinfo_data_file -perfetto_traces_data_file }:lnk_file *; +neverallow perfetto { data_file_type -zoneinfo_data_file -perfetto_traces_data_file }:file ~write; diff --git a/private/shell.te b/private/shell.te index ded9d1f94..7a7ebf462 100644 --- a/private/shell.te +++ b/private/shell.te @@ -38,3 +38,12 @@ allow shell traced_tmpfs:file { read write getattr map }; unix_socket_connect(shell, traced_producer, traced) domain_auto_trans(shell, vendor_shell_exec, vendor_shell) + +# Allow shell binaries to exec the perfetto cmdline util and have that +# transition into its own domain, so that it behaves consistently to +# when exec()-d by statsd. +domain_auto_trans(shell, perfetto_exec, perfetto) + +# Allow shell to read and unlink traces stored in /data/misc/perfetto-traces. +allow shell perfetto_traces_data_file:dir rw_dir_perms; +allow shell perfetto_traces_data_file:file r_file_perms; diff --git a/private/statsd.te b/private/statsd.te index 073c38b40..a51a547a8 100644 --- a/private/statsd.te +++ b/private/statsd.te @@ -37,8 +37,11 @@ binder_call(statsd, system_server) read_logd(statsd) control_logd(statsd) -# Allow to control Perfetto traced and consume its traces. -unix_socket_connect(statsd, traced_consumer, traced) +# Allow to exec the perfetto cmdline client and pass it the trace config on +# stdint through a pipe. It allows statsd to capture traces and hand them +# to Android dropbox. +allow statsd perfetto_exec:file rx_file_perms; +domain_auto_trans(statsd, perfetto_exec, perfetto) # Grant statsd with permissions to register the services. allow statsd { diff --git a/private/su.te b/private/su.te index 6e7fc37d9..16e47bbbf 100644 --- a/private/su.te +++ b/private/su.te @@ -13,6 +13,9 @@ userdebug_or_eng(` # Put the incident command into its domain so it is the same on user, userdebug and eng. domain_auto_trans(su, incident_exec, incident) + # Put the perfetto command into its domain so it is the same on user, userdebug and eng. + domain_auto_trans(su, perfetto_exec, perfetto) + # su is also permissive to permit setenforce. permissive su; diff --git a/private/system_server.te b/private/system_server.te index f8f5e3e49..6ba98f5fd 100644 --- a/private/system_server.te +++ b/private/system_server.te @@ -371,6 +371,11 @@ allow system_server dumpstate:fifo_file append; # with no DAC access to it, for dropbox to read. allow system_server incident_data_file:file read; +# Allow dropbox to read /data/misc/perfetto-traces. Only the fd is sent over +# binder. +allow system_server perfetto_traces_data_file:file read; +allow system_server perfetto:fd use; + # Manage /data/backup. allow system_server backup_data_file:dir create_dir_perms; allow system_server backup_data_file:file create_file_perms; @@ -821,4 +826,3 @@ neverallow system_server { domain -system_server }:process ptrace; # CAP_SYS_RESOURCE was traditionally needed for sensitive /proc/PID # file read access. However, that is now unnecessary (b/34951864) neverallow system_server system_server:global_capability_class_set sys_resource; -