Trace Redaction - Remove comm values from all process free events
Process free events contain a pid and a comm. The timeline uses an
exclusive end bound, so it is not possible to use the event's
timestamp to see of the pid belongs to the package. Instead of using
a fudge value (e.g. time - 1), all process free events will lose their
comm values.
Bug: 318576499
Change-Id: Iceb2adb7f1618a46fe47c8dc5f44b6f68f73701d
diff --git a/Android.bp b/Android.bp
index 1cf094b..43d2027 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12871,6 +12871,7 @@
"src/trace_redaction/proto_util.cc",
"src/trace_redaction/prune_package_list.cc",
"src/trace_redaction/redact_ftrace_event.cc",
+ "src/trace_redaction/redact_process_free.cc",
"src/trace_redaction/redact_sched_switch.cc",
"src/trace_redaction/redact_task_newtask.cc",
"src/trace_redaction/scrub_ftrace_events.cc",
@@ -12895,6 +12896,7 @@
"src/trace_redaction/process_thread_timeline_unittest.cc",
"src/trace_redaction/proto_util_unittest.cc",
"src/trace_redaction/prune_package_list_unittest.cc",
+ "src/trace_redaction/redact_process_free_unittest.cc",
"src/trace_redaction/redact_sched_switch_unittest.cc",
"src/trace_redaction/redact_task_newtask_unittest.cc",
],
diff --git a/src/trace_redaction/BUILD.gn b/src/trace_redaction/BUILD.gn
index bf254c9..e876fac 100644
--- a/src/trace_redaction/BUILD.gn
+++ b/src/trace_redaction/BUILD.gn
@@ -54,6 +54,8 @@
"prune_package_list.h",
"redact_ftrace_event.cc",
"redact_ftrace_event.h",
+ "redact_process_free.cc",
+ "redact_process_free.h",
"redact_sched_switch.cc",
"redact_sched_switch.h",
"redact_task_newtask.cc",
@@ -124,6 +126,7 @@
"process_thread_timeline_unittest.cc",
"proto_util_unittest.cc",
"prune_package_list_unittest.cc",
+ "redact_process_free_unittest.cc",
"redact_sched_switch_unittest.cc",
"redact_task_newtask_unittest.cc",
]
diff --git a/src/trace_redaction/main.cc b/src/trace_redaction/main.cc
index a8a1cdc..003ad78 100644
--- a/src/trace_redaction/main.cc
+++ b/src/trace_redaction/main.cc
@@ -27,6 +27,7 @@
#include "src/trace_redaction/populate_allow_lists.h"
#include "src/trace_redaction/prune_package_list.h"
#include "src/trace_redaction/redact_ftrace_event.h"
+#include "src/trace_redaction/redact_process_free.h"
#include "src/trace_redaction/redact_sched_switch.h"
#include "src/trace_redaction/redact_task_newtask.h"
#include "src/trace_redaction/scrub_ftrace_events.h"
@@ -72,6 +73,7 @@
auto* redact_ftrace_events = redactor.emplace_transform<RedactFtraceEvent>();
redact_ftrace_events->emplace_back<RedactSchedSwitch>();
redact_ftrace_events->emplace_back<RedactTaskNewTask>();
+ redact_ftrace_events->emplace_back<RedactProcessFree>();
Context context;
context.package_name = package_name;
diff --git a/src/trace_redaction/redact_process_free.cc b/src/trace_redaction/redact_process_free.cc
new file mode 100644
index 0000000..654b7b2
--- /dev/null
+++ b/src/trace_redaction/redact_process_free.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_redaction/redact_process_free.h"
+
+#include "src/trace_redaction/proto_util.h"
+
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
+
+namespace perfetto::trace_redaction {
+
+// Redact sched_process_free events.
+//
+// event {
+// timestamp: 6702094703928940
+// pid: 10
+// sched_process_free {
+// comm: "sh"
+// pid: 7973
+// prio: 120
+// }
+// }
+//
+// In the above message, it should be noted that "event.pid" will not be
+// equal to "event.sched_process_free.pid".
+//
+// The timeline treats "start" as inclusive and "end" as exclusive. This means
+// no pid will connect to the target package at a process free event. Because
+// of this, the timeline is not needed.
+RedactProcessFree::RedactProcessFree()
+ : FtraceEventRedaction(
+ protos::pbzero::FtraceEvent::kSchedProcessFreeFieldNumber) {}
+
+base::Status RedactProcessFree::Redact(
+ const Context&,
+ const protos::pbzero::FtraceEvent::Decoder&,
+ protozero::ConstBytes bytes,
+ protos::pbzero::FtraceEvent* event_message) const {
+ protos::pbzero::SchedProcessFreeFtraceEvent::Decoder process_free(bytes);
+
+ // There must be pid. If there's no pid, dropping the event is the safest
+ // option.
+ if (!process_free.has_pid()) {
+ return base::OkStatus();
+ }
+
+ // Avoid making the message until we know that we have prev and next pids.
+ auto* process_free_message = event_message->set_sched_process_free();
+
+ // To read the fields, move the read head back to the start.
+ process_free.Reset();
+
+ for (auto field = process_free.ReadField(); field.valid();
+ field = process_free.ReadField()) {
+ if (field.id() !=
+ protos::pbzero::SchedProcessFreeFtraceEvent::kCommFieldNumber) {
+ proto_util::AppendField(field, process_free_message);
+ }
+ }
+
+ return base::OkStatus();
+}
+
+} // namespace perfetto::trace_redaction
diff --git a/src/trace_redaction/redact_process_free.h b/src/trace_redaction/redact_process_free.h
new file mode 100644
index 0000000..f14fee2
--- /dev/null
+++ b/src/trace_redaction/redact_process_free.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_REDACTION_REDACT_PROCESS_FREE_H_
+#define SRC_TRACE_REDACTION_REDACT_PROCESS_FREE_H_
+
+#include "src/trace_redaction/redact_ftrace_event.h"
+#include "src/trace_redaction/trace_redaction_framework.h"
+
+namespace perfetto::trace_redaction {
+
+// Goes through ftrace events and conditonally removes the comm values from
+// process free events.
+class RedactProcessFree : public FtraceEventRedaction {
+ public:
+ RedactProcessFree();
+
+ base::Status Redact(
+ const Context& context,
+ const protos::pbzero::FtraceEvent::Decoder& event,
+ protozero::ConstBytes bytes,
+ protos::pbzero::FtraceEvent* event_message) const override;
+};
+
+} // namespace perfetto::trace_redaction
+
+#endif // SRC_TRACE_REDACTION_REDACT_PROCESS_FREE_H_
diff --git a/src/trace_redaction/redact_process_free_unittest.cc b/src/trace_redaction/redact_process_free_unittest.cc
new file mode 100644
index 0000000..ee119ca
--- /dev/null
+++ b/src/trace_redaction/redact_process_free_unittest.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_redaction/redact_process_free.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "src/base/test/status_matchers.h"
+#include "src/trace_redaction/trace_redaction_framework.h"
+#include "test/gtest_and_gmock.h"
+
+#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
+#include "protos/perfetto/trace/ftrace/sched.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+
+namespace perfetto::trace_redaction {
+
+class RedactProcessFreeTest : public testing::Test {};
+
+TEST_F(RedactProcessFreeTest, ClearsComm) {
+ protos::gen::FtraceEvent source_event;
+ source_event.set_timestamp(123456789);
+ source_event.set_pid(10);
+
+ auto* process_free = source_event.mutable_sched_process_free();
+ process_free->set_comm("comm-a");
+ process_free->set_pid(11);
+
+ RedactProcessFree redact;
+ Context context;
+
+ protos::pbzero::FtraceEvent::Decoder event_decoder(
+ source_event.SerializeAsString());
+ protozero::HeapBuffered<protos::pbzero::FtraceEvent> event_message;
+
+ auto result =
+ redact.Redact(context, event_decoder, event_decoder.sched_switch(),
+ event_message.get());
+ ASSERT_OK(result) << result.c_message();
+
+ protos::gen::FtraceEvent redacted_event;
+ redacted_event.ParseFromString(event_message.SerializeAsString());
+
+ // No process free event should have been added to the ftrace event.
+ ASSERT_FALSE(redacted_event.has_sched_process_free());
+}
+
+// Even if there is no pid in the process free event, the process free event
+// should still exist but no comm value should be present.
+TEST_F(RedactProcessFreeTest, NoPidClearsEvent) {
+ protos::gen::FtraceEvent source_event;
+ source_event.set_timestamp(123456789);
+ source_event.set_pid(10);
+
+ // Don't add a pid. This should stop the process free event from being added
+ // to the event message.
+ auto* process_free = source_event.mutable_sched_process_free();
+ process_free->set_comm("comm-a");
+
+ RedactProcessFree redact;
+ Context context;
+
+ protos::pbzero::FtraceEvent::Decoder event_decoder(
+ source_event.SerializeAsString());
+ protozero::HeapBuffered<protos::pbzero::FtraceEvent> event_message;
+
+ // Even if the process free event has been dropped, there should be no
+ // resulting error.
+ auto result =
+ redact.Redact(context, event_decoder, event_decoder.sched_switch(),
+ event_message.get());
+ ASSERT_OK(result) << result.c_message();
+
+ protos::gen::FtraceEvent redacted_event;
+ redacted_event.ParseFromString(event_message.SerializeAsString());
+
+ ASSERT_FALSE(redacted_event.has_sched_process_free());
+}
+
+} // namespace perfetto::trace_redaction