summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andrei-Valentin Onea <andreionea@google.com> 2019-02-07 18:07:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-02-07 18:07:24 +0000
commit509d87c201bef48752c94af812137712bbdd059b (patch)
treebd7b08f3b8a6feb1532021c7ac7985e78defa825
parentf0cdc78790c4eecea498be370667d247e16e3ee1 (diff)
parentda01ea5b1cf324ca4d083696618131c5ba1c0cee (diff)
Merge "Add whitelist atom field option Whitelisted atoms can be triggered from any source Test: stats-log-api-gen-test Bug: 119217680 Change-Id: Ia5faed04d696b59ba4ffaab13f5046f943d8a8b7"
-rw-r--r--cmds/statsd/src/atom_field_options.proto2
-rw-r--r--cmds/statsd/src/atoms.proto4
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp57
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h4
-rw-r--r--tools/stats_log_api_gen/Collation.cpp7
-rw-r--r--tools/stats_log_api_gen/Collation.h2
-rw-r--r--tools/stats_log_api_gen/main.cpp16
-rw-r--r--tools/stats_log_api_gen/test.proto18
-rw-r--r--tools/stats_log_api_gen/test_collation.cpp20
9 files changed, 110 insertions, 20 deletions
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index e33bd8c97a07..2a3eee2a7e18 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -82,4 +82,6 @@ extend google.protobuf.FieldOptions {
optional bool is_uid = 50001 [default = false];
optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
+
+ optional bool allow_from_any_uid = 50003 [default = false];
} \ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 07aced6846a4..4f17d69f23f2 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -110,7 +110,7 @@ message Atom {
PacketWakeupOccurred packet_wakeup_occurred = 44;
WallClockTimeShifted wall_clock_time_shifted = 45;
AnomalyDetected anomaly_detected = 46;
- AppBreadcrumbReported app_breadcrumb_reported = 47;
+ AppBreadcrumbReported app_breadcrumb_reported = 47 [(allow_from_any_uid) = true];
AppStartOccurred app_start_occurred = 48;
AppStartCanceled app_start_canceled = 49;
AppStartFullyDrawn app_start_fully_drawn = 50;
@@ -121,7 +121,7 @@ message Atom {
AppStartMemoryStateCaptured app_start_memory_state_captured = 55;
ShutdownSequenceReported shutdown_sequence_reported = 56;
BootSequenceReported boot_sequence_reported = 57;
- DaveyOccurred davey_occurred = 58;
+ DaveyOccurred davey_occurred = 58 [(allow_from_any_uid) = true];
OverlayStateChanged overlay_state_changed = 59;
ForegroundServiceStateChanged foreground_service_state_changed = 60;
CallStateChanged call_state_changed = 61;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index ca681176c54a..6ed6ab500597 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -241,12 +241,22 @@ void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
VLOG("=========================Metric Reports End==========================");
}
-// Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const LogEvent& event) {
- if (!mConfigValid) {
- return;
+
+bool MetricsManager::checkLogCredentials(const LogEvent& event) {
+ if (android::util::AtomsInfo::kWhitelistedAtoms.find(event.GetTagId()) !=
+ android::util::AtomsInfo::kWhitelistedAtoms.end())
+ {
+ return true;
}
+ std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
+ if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
+ VLOG("log source %d not on the whitelist", event.GetUid());
+ return false;
+ }
+ return true;
+}
+bool MetricsManager::eventSanityCheck(const LogEvent& event) {
if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) {
// Check that app breadcrumb reported fields are valid.
status_t err = NO_ERROR;
@@ -256,23 +266,23 @@ void MetricsManager::onLogEvent(const LogEvent& event) {
long appHookUid = event.GetLong(event.size()-2, &err);
if (err != NO_ERROR ) {
VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
- return;
+ return false;
}
int32_t loggerUid = event.GetUid();
if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
appHookUid, loggerUid);
- return;
+ return false;
}
// The state must be from 0,3. This part of code must be manually updated.
long appHookState = event.GetLong(event.size(), &err);
if (err != NO_ERROR ) {
VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
- return;
+ return false;
} else if (appHookState < 0 || appHookState > 3) {
VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
- return;
+ return false;
}
} else if (event.GetTagId() == android::util::DAVEY_OCCURRED) {
// Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
@@ -283,31 +293,42 @@ void MetricsManager::onLogEvent(const LogEvent& event) {
long jankUid = event.GetLong(1, &err);
if (err != NO_ERROR ) {
VLOG("Davey occurred had error when parsing the uid");
- return;
+ return false;
}
int32_t loggerUid = event.GetUid();
if (loggerUid != jankUid && loggerUid != AID_STATSD) {
VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
loggerUid);
- return;
+ return false;
}
long duration = event.GetLong(event.size(), &err);
if (err != NO_ERROR ) {
VLOG("Davey occurred had error when parsing the duration");
- return;
+ return false;
} else if (duration > 100000) {
VLOG("Davey duration is unreasonably long: %ld", duration);
- return;
- }
- } else {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
- VLOG("log source %d not on the whitelist", event.GetUid());
- return;
+ return false;
}
}
+ return true;
+}
+
+// Consume the stats log if it's interesting to this metric.
+void MetricsManager::onLogEvent(const LogEvent& event) {
+ if (!mConfigValid) {
+ return;
+ }
+
+ if (!checkLogCredentials(event)) {
+ return;
+ }
+
+ if (!eventSanityCheck(event)) {
+ return;
+ }
+
int tagId = event.GetTagId();
int64_t eventTimeNs = event.GetElapsedTimestampNs();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 80982c37dc6a..fdc28ea7f219 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -49,6 +49,10 @@ public:
// Return whether the configuration is valid.
bool isConfigValid() const;
+ bool checkLogCredentials(const LogEvent& event);
+
+ bool eventSanityCheck(const LogEvent& event);
+
void onLogEvent(const LogEvent& event);
void onAnomalyAlarmFired(
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 257043b30704..a8d970edaa85 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -48,6 +48,7 @@ AtomDecl::AtomDecl(const AtomDecl& that)
primaryFields(that.primaryFields),
exclusiveField(that.exclusiveField),
uidField(that.uidField),
+ whitelisted(that.whitelisted),
binaryFields(that.binaryFields) {}
AtomDecl::AtomDecl(int c, const string& n, const string& m)
@@ -162,6 +163,7 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
vector<java_type_t> *signature) {
int errorCount = 0;
+
// Build a sorted list of the fields. Descriptor has them in source file
// order.
map<int, const FieldDescriptor *> fields;
@@ -387,6 +389,11 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) {
const Descriptor *atom = atomField->message_type();
AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
+
+ if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
+ atomDecl.whitelisted = true;
+ }
+
vector<java_type_t> signature;
errorCount += collate_atom(atom, &atomDecl, &signature);
if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) {
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 450b30547c21..6b86b862dfad 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -89,6 +89,8 @@ struct AtomDecl {
int uidField = 0;
+ bool whitelisted = false;
+
vector<int> binaryFields;
AtomDecl();
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 4491a8567441..55440d2261d3 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -158,6 +158,20 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
}
}
}
+
+ fprintf(out, "};\n");
+ fprintf(out, "\n");
+
+ fprintf(out,
+ "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n");
+ for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+ atom != atoms.decls.end(); atom++) {
+ if (atom->whitelisted) {
+ string constant = make_constant_name(atom->name);
+ fprintf(out, " %s,\n", constant.c_str());
+ }
+ }
+
fprintf(out, "};\n");
fprintf(out, "\n");
@@ -728,6 +742,8 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio
fprintf(out,
" const static std::map<int, std::vector<int>> "
"kBytesFieldAtoms;");
+ fprintf(out,
+ " const static std::set<int> kWhitelistedAtoms;\n");
fprintf(out, "};\n");
fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 3be87d95df15..24ebf4de031a 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -195,4 +195,22 @@ message GoodStateAtom3 {
[(android.os.statsd.state_field_option).option = PRIMARY];
optional int32 state = 3
[(android.os.statsd.state_field_option).option = EXCLUSIVE];
+}
+
+message WhitelistedAtom {
+ optional int32 field = 1;
+}
+
+message NonWhitelistedAtom {
+ optional int32 field = 1;
+}
+
+message ListedAtoms {
+ oneof event {
+ // Atoms can be whitelisted i.e. they can be triggered by any source
+ WhitelistedAtom whitelisted_atom = 1 [(android.os.statsd.allow_from_any_uid) = true];
+ // Atoms are not whitelisted by default, so they can only be triggered
+ // by whitelisted sources
+ NonWhitelistedAtom non_whitelisted_atom = 2;
+ }
} \ No newline at end of file
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index ad3bffacd442..dc585c1c5dd1 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -226,5 +226,25 @@ TEST(CollationTest, FailOnBadBinaryFieldAtom) {
EXPECT_TRUE(errorCount > 0);
}
+TEST(CollationTest, PassOnWhitelistedAtom) {
+ Atoms atoms;
+ int errorCount =
+ collate_atoms(ListedAtoms::descriptor(), &atoms);
+ EXPECT_EQ(errorCount, 0);
+ EXPECT_EQ(atoms.decls.size(), 2ul);
+}
+
+TEST(CollationTest, RecogniseWhitelistedAtom) {
+ Atoms atoms;
+ collate_atoms(ListedAtoms::descriptor(), &atoms);
+ for (const auto& atomDecl : atoms.decls) {
+ if (atomDecl.code == 1) {
+ EXPECT_TRUE(atomDecl.whitelisted);
+ } else {
+ EXPECT_FALSE(atomDecl.whitelisted);
+ }
+ }
+}
+
} // namespace stats_log_api_gen
} // namespace android \ No newline at end of file