InputTracer: Adjust traced event sensitivity based on allow-list
An allow-list of packages will be defined in the perfetto config for
input traces. We can only allow an event to traced completely (i.e.
treated as a non-sensitive event) if _all_ of the UIDs that the event is
targeting are allow-listed for the trace.
In each trace instace, we maintain a cache of whether UIDs seen so far
are allow-listed. Since the allow-list is specified through a list of
package names, we must query PackageManager through the InputDispatcher
policy to look up the packages that correspond to each UID that we see.
Bug: 210460522
Test: manual with perfetto
Change-Id: I9c19a5ed941ebc239dccc0363cc6553733e16afd
diff --git a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
index bed753c..b76bec3 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
@@ -22,6 +22,7 @@
#include <android-base/logging.h>
#include <perfetto/trace/android/android_input_event.pbzero.h>
+#include <private/android_filesystem_config.h>
namespace android::inputdispatcher::trace::impl {
@@ -29,6 +30,17 @@
constexpr auto INPUT_EVENT_TRACE_DATA_SOURCE_NAME = "android.input.inputevent";
+bool isPermanentlyAllowed(gui::Uid uid) {
+ switch (uid.val()) {
+ case AID_SYSTEM:
+ case AID_SHELL:
+ case AID_ROOT:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace
// --- PerfettoBackend::InputEventDataSource ---
@@ -55,6 +67,22 @@
InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) { ctx.Flush(); });
}
+void PerfettoBackend::InputEventDataSource::initializeUidMap(GetPackageUid getPackageUid) {
+ if (mUidMap.has_value()) {
+ return;
+ }
+
+ mUidMap = {{}};
+ for (const auto& rule : mConfig.rules) {
+ for (const auto& package : rule.matchAllPackages) {
+ mUidMap->emplace(package, getPackageUid(package));
+ }
+ for (const auto& package : rule.matchAnyPackages) {
+ mUidMap->emplace(package, getPackageUid(package));
+ }
+ }
+}
+
bool PerfettoBackend::InputEventDataSource::shouldIgnoreTracedInputEvent(
const EventType& type) const {
if (!getFlags().test(TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS)) {
@@ -77,7 +105,6 @@
return rule.level;
}
}
-
// The event is not traced if it matched zero rules.
return TraceLevel::TRACE_LEVEL_NONE;
}
@@ -86,10 +113,31 @@
const TracedEventArgs& args) const {
// By default, a rule will match all events. Return early if the rule does not match.
+ // Match the event if it is directed to a secure window.
if (rule.matchSecure.has_value() && *rule.matchSecure != args.isSecure) {
return false;
}
+ // Match the event if all of its target packages are explicitly allowed in the "match all" list.
+ if (!rule.matchAllPackages.empty() &&
+ !std::all_of(args.targets.begin(), args.targets.end(), [&](const auto& uid) {
+ return isPermanentlyAllowed(uid) ||
+ std::any_of(rule.matchAllPackages.begin(), rule.matchAllPackages.end(),
+ [&](const auto& pkg) { return uid == mUidMap->at(pkg); });
+ })) {
+ return false;
+ }
+
+ // Match the event if any of its target packages are allowed in the "match any" list.
+ if (!rule.matchAnyPackages.empty() &&
+ !std::any_of(args.targets.begin(), args.targets.end(), [&](const auto& uid) {
+ return std::any_of(rule.matchAnyPackages.begin(), rule.matchAnyPackages.end(),
+ [&](const auto& pkg) { return uid == mUidMap->at(pkg); });
+ })) {
+ return false;
+ }
+
+ // The event matches all matchers specified in the rule.
return true;
}
@@ -99,7 +147,8 @@
std::atomic<int32_t> PerfettoBackend::sNextInstanceId{1};
-PerfettoBackend::PerfettoBackend() {
+PerfettoBackend::PerfettoBackend(GetPackageUid getPackagesForUid)
+ : mGetPackageUid(getPackagesForUid) {
// Use a once-flag to ensure that the data source is only registered once per boot, since
// we never unregister the InputEventDataSource.
std::call_once(sDataSourceRegistrationFlag, []() {
@@ -120,6 +169,7 @@
const TracedEventArgs& args) {
InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
auto dataSource = ctx.GetDataSourceLocked();
+ dataSource->initializeUidMap(mGetPackageUid);
if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
return;
}
@@ -139,6 +189,7 @@
void PerfettoBackend::traceKeyEvent(const TracedKeyEvent& event, const TracedEventArgs& args) {
InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
auto dataSource = ctx.GetDataSourceLocked();
+ dataSource->initializeUidMap(mGetPackageUid);
if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
return;
}
@@ -159,6 +210,7 @@
const TracedEventArgs& args) {
InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
auto dataSource = ctx.GetDataSourceLocked();
+ dataSource->initializeUidMap(mGetPackageUid);
if (!dataSource->getFlags().test(TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH)) {
return;
}