Allow dumpstate to snapshot traces and attach them to bug reports
Feature description: if a background trace is happening at the
time dumpstate is invoked, the tracing daemon will snapshot
the trace into a fixed path (/data/misc/perfetto-traces/bugreport/).
Dumpstate will attach the trace, if present, to the bugreport.
From a SELinux viewpoint this involves the following permissions:
- Allow dumpstate to exec+trans perfetto --save-for-bugreport
(this will just send an IPC to traced, which will save the trace).
- Allow dumpstate to list, read and unlink the trace file.
- Create a dedicated label for bugreport traces, to prevent that
dumpstate gets access to other traces not meant for bug reporting.
Note that this does NOT allow dumpstate to serialze arbitary traces.
Traces must be marked as "eligible for bugreport" upfront in the
trace config (which is not under dumpstate control), by
setting bugreport_score > 0.
Design doc: go/perfetto-betterbug
Bug: 170334305
Test: manual:
1. start a perfetto trace with bugreport_score > 0
2. adb shell dumpstate
3. check that the bugreport zip contains the trace
Change-Id: I259c3ee9d5be08d6b22c796b32875d7de703a230
diff --git a/private/compat/30.0/30.0.ignore.cil b/private/compat/30.0/30.0.ignore.cil
index dce98c3..b239831 100644
--- a/private/compat/30.0/30.0.ignore.cil
+++ b/private/compat/30.0/30.0.ignore.cil
@@ -19,6 +19,7 @@
dmabuf_heap_device
dmabuf_system_heap_device
dmabuf_system_secure_heap_device
+ dumpstate_tmpfs
framework_watchdog_config_prop
game_service
gki_apex_prepostinstall
diff --git a/private/dumpstate.te b/private/dumpstate.te
index 13c2c5e..2b7b228 100644
--- a/private/dumpstate.te
+++ b/private/dumpstate.te
@@ -1,4 +1,5 @@
typeattribute dumpstate coredomain;
+type dumpstate_tmpfs, file_type;
init_daemon_domain(dumpstate)
@@ -82,3 +83,19 @@
binder_call(dumpstate, gsid)
r_dir_file(dumpstate, ota_metadata_file)
+
+# For starting (and killing) perfetto --save-for-bugreport. If a labelled trace
+# is being recorded, the command above will serialize it into
+# /data/misc/perfetto-traces/bugreport/*.pftrace .
+domain_auto_trans(dumpstate, perfetto_exec, perfetto)
+allow dumpstate perfetto:process signal;
+allow dumpstate perfetto_traces_data_file:dir { search };
+allow dumpstate perfetto_traces_bugreport_data_file:dir rw_dir_perms;
+allow dumpstate perfetto_traces_bugreport_data_file:file { r_file_perms unlink };
+
+# When exec-ing /system/bin/perfetto, dumpstates redirects stdio to /dev/null
+# (which is labelled as dumpstate_tmpfs) to avoid leaking a FD to the bugreport
+# zip file. These rules are to allow perfetto.te to inherit dumpstate's
+# /dev/null.
+allow perfetto dumpstate_tmpfs:file rw_file_perms;
+allow perfetto dumpstate:fd use;
diff --git a/private/file.te b/private/file.te
index 993306b..1a53c33 100644
--- a/private/file.te
+++ b/private/file.te
@@ -10,6 +10,9 @@
# /data/misc/perfetto-traces for perfetto traces
type perfetto_traces_data_file, file_type, data_file_type, core_data_file_type;
+# /data/misc/perfetto-traces/bugreport for perfetto traces for bugreports.
+type perfetto_traces_bugreport_data_file, file_type, data_file_type, core_data_file_type;
+
# /data/misc/perfetto-configs for perfetto configs
type perfetto_configs_data_file, file_type, data_file_type, core_data_file_type;
diff --git a/private/file_contexts b/private/file_contexts
index 98300cb..9d28d5c 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -580,8 +580,9 @@
/data/misc/net(/.*)? u:object_r:net_data_file:s0
/data/misc/network_watchlist(/.*)? u:object_r:network_watchlist_data_file:s0
/data/misc/nfc/logs(/.*)? u:object_r:nfc_logs_data_file:s0
-/data/misc/perfetto-traces(/.*)? u:object_r:perfetto_traces_data_file:s0
-/data/misc/perfetto-configs(/.*)? u:object_r:perfetto_configs_data_file:s0
+/data/misc/perfetto-traces/bugreport(.*)? u:object_r:perfetto_traces_bugreport_data_file:s0
+/data/misc/perfetto-traces(/.*)? u:object_r:perfetto_traces_data_file:s0
+/data/misc/perfetto-configs(/.*)? u:object_r:perfetto_configs_data_file:s0
/data/misc/prereboot(/.*)? u:object_r:prereboot_data_file:s0
/data/misc/profcollectd(/.*)? u:object_r:profcollectd_data_file:s0
/data/misc/radio(/.*)? u:object_r:radio_core_data_file:s0
diff --git a/private/priv_app.te b/private/priv_app.te
index 6a60cd1..dde8f09 100644
--- a/private/priv_app.te
+++ b/private/priv_app.te
@@ -65,6 +65,14 @@
# Allow traceur to pass file descriptors through a content provider to betterbug
allow priv_app trace_data_file:file { getattr read };
+# Allow the bug reporting frontend to read the presence and timestamp of the
+# trace attached to the bugreport (but not its contents, which will go in the
+# usual bugreport .zip file). This is used by the bug reporting UI to tell if
+# the bugreport will contain a system trace or not while the bugreport is still
+# in progress.
+allow priv_app perfetto_traces_bugreport_data_file:dir r_dir_perms;
+allow priv_app perfetto_traces_bugreport_data_file:file { getattr };
+
# Allow verifier to access staged apks.
allow priv_app { apk_tmp_file apk_private_tmp_file }:dir r_dir_perms;
allow priv_app { apk_tmp_file apk_private_tmp_file }:file r_file_perms;
diff --git a/private/traced.te b/private/traced.te
index 2410d7e..fcbe46d 100644
--- a/private/traced.te
+++ b/private/traced.te
@@ -28,6 +28,9 @@
# Allow the service to create new files within /data/misc/perfetto-traces.
allow traced perfetto_traces_data_file:file create_file_perms;
allow traced perfetto_traces_data_file:dir rw_dir_perms;
+# ... and /data/misc/perfetto-traces/bugreport*
+allow traced perfetto_traces_bugreport_data_file:file create_file_perms;
+allow traced perfetto_traces_bugreport_data_file:dir rw_dir_perms;
# Allow traceur to pass open file descriptors to traced, so traced can directly
# write into the output file without doing roundtrips over IPC.
@@ -82,6 +85,7 @@
neverallow traced {
data_file_type
-perfetto_traces_data_file
+ -perfetto_traces_bugreport_data_file
-system_data_file
-system_data_root_file
# TODO(b/72998741) Remove vendor_data_file exemption. Further restricted in a
@@ -97,6 +101,7 @@
data_file_type
-zoneinfo_data_file
-perfetto_traces_data_file
+ -perfetto_traces_bugreport_data_file
-trace_data_file
with_native_coverage(`-method_trace_data_file')
}:file ~write;