perfetto: allow producers to supply shared memory
This concerns the data transfer between an untrusted producer process,
and the tracing service (traced daemon). They communicate over a
combination of a unix socket and shared memory.
Normally, the service creates the shared memory region, and hands it off
to the producer process (see perfetto_producer() macro). This patch
allows for an alternative scheme, where the producer process is allowed
to create the shared memory region, which will then be adopted by the
tracing service. The service already inherently doesn't trust the
producer, so it'll validate that the shared memory is appropriately
sealed before using it.
The immediate use-case is chrome's go/perfetto-startup-tracing-v2. But
this mode has advantages (e.g. being able to write to the shared memory
before connecting) for other producer domains as well.
Bug: 148841422
Change-Id: I90f864b900958792553f0208f4a0041dbf2892cc
diff --git a/private/traced.te b/private/traced.te
index 42c6704..7ecfb7f 100644
--- a/private/traced.te
+++ b/private/traced.te
@@ -36,6 +36,23 @@
allow traced iorapd:fd use;
allow traced iorapd_tmpfs:file { read write };
+# Allow traced to use shared memory supplied by producers. Typically, traced
+# (i.e. the tracing service) creates the shared memory used for data transfer
+# from the producer. This rule allows an alternative scheme, where the producer
+# creates the shared memory, that is then adopted by traced (after validating
+# that it is appropriately sealed).
+# This list has to replicate the tmpfs domains of all applicable domains that
+# have perfetto_producer() macro applied to them.
+# perfetto_tmpfs excluded as it should never need to use the producer-supplied
+# shared memory scheme.
+allow traced {
+ appdomain_tmpfs
+ heapprofd_tmpfs
+ surfaceflinger_tmpfs
+ traced_probes_tmpfs
+ userdebug_or_eng(`system_server_tmpfs')
+}:file { getattr map read write };
+
# Allow traced to notify Traceur when a trace ends by setting the
# sys.trace.trace_end_signal property.
set_prop(traced, system_trace_prop)
diff --git a/private/traced_probes.te b/private/traced_probes.te
index 28538da..dd6ece0 100644
--- a/private/traced_probes.te
+++ b/private/traced_probes.te
@@ -1,8 +1,10 @@
# Perfetto tracing probes, has tracefs access.
type traced_probes_exec, system_file_type, exec_type, file_type;
+type traced_probes_tmpfs, file_type;
# Allow init to exec the daemon.
init_daemon_domain(traced_probes)
+tmpfs_domain(traced_probes)
# Write trace data to the Perfetto traced damon. This requires connecting to its
# producer socket and obtaining a (per-process) tmpfs fd.
diff --git a/public/te_macros b/public/te_macros
index 2d0e050..dcecc23 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -748,6 +748,9 @@
###################################
# perfetto_producer(domain)
# Allow processes within the domain to write data to Perfetto.
+# When applying this macro, you might need to also allow traced to use the
+# producer tmpfs domain, if the producer will be the one creating the shared
+# memory.
define(`perfetto_producer', `
allow $1 traced:fd use;
allow $1 traced_tmpfs:file { read write getattr map };