diff options
| author | 2019-02-07 18:07:24 +0000 | |
|---|---|---|
| committer | 2019-02-07 18:07:24 +0000 | |
| commit | 509d87c201bef48752c94af812137712bbdd059b (patch) | |
| tree | bd7b08f3b8a6feb1532021c7ac7985e78defa825 | |
| parent | f0cdc78790c4eecea498be370667d247e16e3ee1 (diff) | |
| parent | da01ea5b1cf324ca4d083696618131c5ba1c0cee (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.proto | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/atoms.proto | 4 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricsManager.cpp | 57 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricsManager.h | 4 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/Collation.cpp | 7 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/Collation.h | 2 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/main.cpp | 16 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/test.proto | 18 | ||||
| -rw-r--r-- | tools/stats_log_api_gen/test_collation.cpp | 20 |
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 |