From 407537f798c443a2252fd3bbbd1535f7d6fabc53 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 21 Feb 2017 16:19:08 -0800 Subject: [PATCH] logd: add getEventTag id= command This is the precursor for "Plan B" recovery when access to /dev/event-log-tags is blocked to untrusted zones. Also deals with mitigating issues with long-lived mappings that do not update /dev/event-log-tags when dynamically changed. Test: gTest logd-unit-test --gtest_filter=logd.getEventTag_42 Bug: 31456426 Bug: 35326290 Change-Id: I3db2e73763603727a369da3952c5ab4cf709f901 --- logd/CommandListener.cpp | 16 ++++++++++++++++ logd/LogBuffer.h | 3 +++ logd/LogTags.cpp | 5 +++++ logd/LogTags.h | 1 + logd/tests/logd_test.cpp | 17 +++++++++++++++++ 5 files changed, 42 insertions(+) diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index 74e0ea576..6ad735152 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp @@ -301,6 +301,7 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient *cli, const char *name = NULL; const char *format = NULL; + const char *id = NULL; for (int i = 1; i < argc; ++i) { static const char _name[] = "name="; if (!strncmp(argv[i], _name, strlen(_name))) { @@ -313,6 +314,21 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient *cli, format = argv[i] + strlen(_format); continue; } + + static const char _id[] = "id="; + if (!strncmp(argv[i], _id, strlen(_id))) { + id = argv[i] + strlen(_id); + continue; + } + } + + if (id) { + if (format || name) { + cli->sendMsg("can not mix id= with either format= or name="); + return 0; + } + cli->sendMsg(package_string(mBuf.formatEntry(atoi(id), uid)).c_str()); + return 0; } cli->sendMsg(package_string(mBuf.formatGetEventTag(uid, diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index da63e125e..9feef32e7 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -140,6 +140,9 @@ public: const char *name, const char *format) { return tags.formatGetEventTag(uid, name, format); } + std::string formatEntry(uint32_t tag, uid_t uid) { + return tags.formatEntry(tag, uid); + } const char *tagToName(uint32_t tag) { return tags.tagToName(tag); } // helper must be protected directly or implicitly by lock()/unlock() diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp index a109592ba..64aa219e9 100644 --- a/logd/LogTags.cpp +++ b/logd/LogTags.cpp @@ -836,6 +836,11 @@ std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid, return ret; } +std::string LogTags::formatEntry(uint32_t tag, uid_t uid) { + android::RWLock::AutoRLock readLock(rwlock); + return formatEntry_locked(tag, uid); +} + std::string LogTags::formatGetEventTag(uid_t uid, const char* name, const char* format) { bool all = name && (name[0] == '*') && !name[1]; diff --git a/logd/LogTags.h b/logd/LogTags.h index 37a6d9632..4457c462f 100644 --- a/logd/LogTags.h +++ b/logd/LogTags.h @@ -106,6 +106,7 @@ public: // reverse lookup from tag const char* tagToName(uint32_t tag) const; const char* tagToFormat(uint32_t tag) const; + std::string formatEntry(uint32_t tag, uid_t uid); // find associated tag uint32_t nameToTag(const char* name) const; diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp index adf583b81..8a35059c2 100644 --- a/logd/tests/logd_test.cpp +++ b/logd/tests/logd_test.cpp @@ -836,6 +836,23 @@ TEST(logd, getEventTag_list) { #endif } +TEST(logd, getEventTag_42) { +#ifdef __ANDROID__ + char buffer[256]; + memset(buffer, 0, sizeof(buffer)); + snprintf(buffer, sizeof(buffer), "getEventTag id=42"); + send_to_control(buffer, sizeof(buffer)); + buffer[sizeof(buffer) - 1] = '\0'; + char *cp; + long ret = strtol(buffer, &cp, 10); + EXPECT_GT(ret, 16); + EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != NULL); + EXPECT_TRUE(strstr(buffer, "answer") != NULL); +#else + GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif +} + TEST(logd, getEventTag_newentry) { #ifdef __ANDROID__ char buffer[256];