From 1a12ae3a256d4d8a0ad08d1ed5e37d7178705287 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Fri, 1 May 2020 16:13:18 -0700 Subject: [PATCH 1/5] logd: decouple LogTags from LogBuffer LogBuffer needs a pointer to LogTags, but it should not own the instance. It should not provide accessors into LogTags either. Also, clean up CommandListener a bit. Test: logging unit tests Change-Id: Ic0c86a2bac0c4dd80262278588b9fdc2326dbe5b --- logd/CommandListener.cpp | 94 +++++++---------------------- logd/CommandListener.h | 92 +++++++++------------------- logd/LogBuffer.cpp | 6 +- logd/LogBuffer.h | 22 ++----- logd/fuzz/log_buffer_log_fuzzer.cpp | 3 +- logd/main.cpp | 8 ++- 6 files changed, 66 insertions(+), 159 deletions(-) diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index 694b5fa3c..1e7a33a2d 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp @@ -38,37 +38,20 @@ #include "LogCommand.h" #include "LogUtils.h" -CommandListener::CommandListener(LogBuffer* buf, LogReader* /*reader*/, - LogListener* /*swl*/) - : FrameworkListener(getLogSocket()) { - // registerCmd(new ShutdownCmd(buf, writer, swl)); - registerCmd(new ClearCmd(buf)); - registerCmd(new GetBufSizeCmd(buf)); - registerCmd(new SetBufSizeCmd(buf)); - registerCmd(new GetBufSizeUsedCmd(buf)); - registerCmd(new GetStatisticsCmd(buf)); - registerCmd(new SetPruneListCmd(buf)); - registerCmd(new GetPruneListCmd(buf)); - registerCmd(new GetEventTagCmd(buf)); - registerCmd(new ReinitCmd()); +CommandListener::CommandListener(LogBuffer* buf, LogTags* tags) + : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags) { + registerCmd(new ClearCmd(this)); + registerCmd(new GetBufSizeCmd(this)); + registerCmd(new SetBufSizeCmd(this)); + registerCmd(new GetBufSizeUsedCmd(this)); + registerCmd(new GetStatisticsCmd(this)); + registerCmd(new SetPruneListCmd(this)); + registerCmd(new GetPruneListCmd(this)); + registerCmd(new GetEventTagCmd(this)); + registerCmd(new ReinitCmd(this)); registerCmd(new ExitCmd(this)); } -CommandListener::ShutdownCmd::ShutdownCmd(LogReader* reader, LogListener* swl) - : LogCommand("shutdown"), mReader(*reader), mSwl(*swl) { -} - -int CommandListener::ShutdownCmd::runCommand(SocketClient* /*cli*/, - int /*argc*/, char** /*argv*/) { - mSwl.stopListener(); - mReader.stopListener(); - exit(0); -} - -CommandListener::ClearCmd::ClearCmd(LogBuffer* buf) - : LogCommand("clear"), mBuf(*buf) { -} - static void setname() { static bool name_set; if (!name_set) { @@ -96,14 +79,10 @@ int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc, return 0; } - cli->sendMsg(mBuf.clear((log_id_t)id, uid) ? "busy" : "success"); + cli->sendMsg(buf()->clear((log_id_t)id, uid) ? "busy" : "success"); return 0; } -CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer* buf) - : LogCommand("getLogSize"), mBuf(*buf) { -} - int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc, char** argv) { setname(); @@ -118,17 +97,13 @@ int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc, return 0; } - unsigned long size = mBuf.getSize((log_id_t)id); + unsigned long size = buf()->getSize((log_id_t)id); char buf[512]; snprintf(buf, sizeof(buf), "%lu", size); cli->sendMsg(buf); return 0; } -CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer* buf) - : LogCommand("setLogSize"), mBuf(*buf) { -} - int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc, char** argv) { setname(); @@ -149,7 +124,7 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc, } unsigned long size = atol(argv[2]); - if (mBuf.setSize((log_id_t)id, size)) { + if (buf()->setSize((log_id_t)id, size)) { cli->sendMsg("Range Error"); return 0; } @@ -158,10 +133,6 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc, return 0; } -CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer* buf) - : LogCommand("getLogSizeUsed"), mBuf(*buf) { -} - int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc, char** argv) { setname(); @@ -176,17 +147,13 @@ int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc, return 0; } - unsigned long size = mBuf.getSizeUsed((log_id_t)id); + unsigned long size = buf()->getSizeUsed((log_id_t)id); char buf[512]; snprintf(buf, sizeof(buf), "%lu", size); cli->sendMsg(buf); return 0; } -CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer* buf) - : LogCommand("getStatistics"), mBuf(*buf) { -} - // This returns a string with a length prefix with the format \n\n\f. The length // prefix includes the length of the prefix itself. static std::string PackageString(const std::string& str) { @@ -241,25 +208,17 @@ int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc, } } - cli->sendMsg(PackageString(mBuf.formatStatistics(uid, pid, logMask)).c_str()); + cli->sendMsg(PackageString(buf()->formatStatistics(uid, pid, logMask)).c_str()); return 0; } -CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer* buf) - : LogCommand("getPruneList"), mBuf(*buf) { -} - int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli, int /*argc*/, char** /*argv*/) { setname(); - cli->sendMsg(PackageString(mBuf.formatPrune()).c_str()); + cli->sendMsg(PackageString(buf()->formatPrune()).c_str()); return 0; } -CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer* buf) - : LogCommand("setPruneList"), mBuf(*buf) { -} - int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc, char** argv) { setname(); @@ -276,7 +235,7 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc, str += argv[i]; } - int ret = mBuf.initPrune(str.c_str()); + int ret = buf()->initPrune(str.c_str()); if (ret) { cli->sendMsg("Invalid"); @@ -288,10 +247,6 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc, return 0; } -CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer* buf) - : LogCommand("getEventTag"), mBuf(*buf) { -} - int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc, char** argv) { setname(); @@ -328,18 +283,15 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc, cli->sendMsg("can not mix id= with either format= or name="); return 0; } - cli->sendMsg(PackageString(mBuf.formatEntry(atoi(id), uid)).c_str()); + cli->sendMsg(PackageString(tags()->formatEntry(atoi(id), uid)).c_str()); return 0; } - cli->sendMsg(PackageString(mBuf.formatGetEventTag(uid, name, format)).c_str()); + cli->sendMsg(PackageString(tags()->formatGetEventTag(uid, name, format)).c_str()); return 0; } -CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") { -} - int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/, char** /*argv*/) { setname(); @@ -351,16 +303,12 @@ int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/, return 0; } -CommandListener::ExitCmd::ExitCmd(CommandListener* parent) - : LogCommand("EXIT"), mParent(*parent) { -} - int CommandListener::ExitCmd::runCommand(SocketClient* cli, int /*argc*/, char** /*argv*/) { setname(); cli->sendMsg("success"); - release(cli); + parent_->release(cli); return 0; } diff --git a/logd/CommandListener.h b/logd/CommandListener.h index ed9941938..80597b2a0 100644 --- a/logd/CommandListener.h +++ b/logd/CommandListener.h @@ -14,85 +14,53 @@ * limitations under the License. */ -#ifndef _COMMANDLISTENER_H__ -#define _COMMANDLISTENER_H__ +#pragma once #include + #include "LogBuffer.h" #include "LogCommand.h" #include "LogListener.h" #include "LogReader.h" +#include "LogTags.h" // See main.cpp for implementation void reinit_signal_handler(int /*signal*/); class CommandListener : public FrameworkListener { - public: - CommandListener(LogBuffer* buf, LogReader* reader, LogListener* swl); - virtual ~CommandListener() { - } + public: + CommandListener(LogBuffer* buf, LogTags* tags); + virtual ~CommandListener() {} - private: + private: static int getLogSocket(); - class ShutdownCmd : public LogCommand { - LogReader& mReader; - LogListener& mSwl; + LogBuffer* buf_; + LogTags* tags_; - public: - ShutdownCmd(LogReader* reader, LogListener* swl); - virtual ~ShutdownCmd() { - } - int runCommand(SocketClient* c, int argc, char** argv); - }; - -#define LogBufferCmd(name) \ +#define LogCmd(name, command_string) \ class name##Cmd : public LogCommand { \ - LogBuffer& mBuf; \ + public: \ + explicit name##Cmd(CommandListener* parent) \ + : LogCommand(#command_string), parent_(parent) {} \ + virtual ~name##Cmd() {} \ + int runCommand(SocketClient* c, int argc, char** argv); \ \ - public: \ - explicit name##Cmd(LogBuffer* buf); \ - virtual ~name##Cmd() { \ - } \ - int runCommand(SocketClient* c, int argc, char** argv); \ + private: \ + LogBuffer* buf() const { return parent_->buf_; } \ + LogTags* tags() const { return parent_->tags_; } \ + CommandListener* parent_; \ } - LogBufferCmd(Clear); - LogBufferCmd(GetBufSize); - LogBufferCmd(SetBufSize); - LogBufferCmd(GetBufSizeUsed); - LogBufferCmd(GetStatistics); - LogBufferCmd(GetPruneList); - LogBufferCmd(SetPruneList); - LogBufferCmd(GetEventTag); - -#define LogCmd(name) \ - class name##Cmd : public LogCommand { \ - public: \ - name##Cmd(); \ - virtual ~name##Cmd() { \ - } \ - int runCommand(SocketClient* c, int argc, char** argv); \ - } - - LogCmd(Reinit); - -#define LogParentCmd(name) \ - class name##Cmd : public LogCommand { \ - CommandListener& mParent; \ - \ - public: \ - name##Cmd(); \ - explicit name##Cmd(CommandListener* parent); \ - virtual ~name##Cmd() { \ - } \ - int runCommand(SocketClient* c, int argc, char** argv); \ - void release(SocketClient* c) { \ - mParent.release(c); \ - } \ - } - - LogParentCmd(Exit); + LogCmd(Clear, clear); + LogCmd(GetBufSize, getLogSize); + LogCmd(SetBufSize, setLogSize); + LogCmd(GetBufSizeUsed, getLogSizeUsed); + LogCmd(GetStatistics, getStatistics); + LogCmd(GetPruneList, getPruneList); + LogCmd(SetPruneList, setPruneList); + LogCmd(GetEventTag, getEventTag); + LogCmd(Reinit, reinit); + LogCmd(Exit, EXIT); +#undef LogCmd }; - -#endif diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 36273deac..443fd980a 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -109,8 +109,8 @@ void LogBuffer::init() { LogTimeEntry::unlock(); } -LogBuffer::LogBuffer(LastLogTimes* times) - : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times) { +LogBuffer::LogBuffer(LastLogTimes* times, LogTags* tags) + : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times), tags_(tags) { pthread_rwlock_init(&mLogElementsLock, nullptr); log_id_for_each(i) { @@ -232,7 +232,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, const char* tag = nullptr; size_t tag_len = 0; if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) { - tag = tagToName(elem->getTag()); + tag = tags_->tagToName(elem->getTag()); if (tag) { tag_len = strlen(tag); } diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index 458fbbbd2..b8e64d03b 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef _LOGD_LOG_BUFFER_H__ -#define _LOGD_LOG_BUFFER_H__ +#pragma once #include @@ -98,8 +97,6 @@ class LogBuffer { bool monotonic; - LogTags tags; - LogBufferElement* lastLoggedElements[LOG_ID_MAX]; LogBufferElement* droppedElements[LOG_ID_MAX]; void log(LogBufferElement* elem); @@ -107,7 +104,7 @@ class LogBuffer { public: LastLogTimes& mTimes; - explicit LogBuffer(LastLogTimes* times); + LogBuffer(LastLogTimes* times, LogTags* tags); ~LogBuffer(); void init(); bool isMonotonic() { @@ -143,17 +140,6 @@ class LogBuffer { return mPrune.format(); } - std::string formatGetEventTag(uid_t uid, 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 wrlock()/unlock() const char* pidToName(pid_t pid) { return stats.pidToName(pid); @@ -186,6 +172,6 @@ class LogBuffer { // Returns an iterator to the oldest element for a given log type, or mLogElements.end() if // there are no logs for the given log type. Requires mLogElementsLock to be held. LogBufferElementCollection::iterator GetOldest(log_id_t log_id); -}; -#endif // _LOGD_LOG_BUFFER_H__ + LogTags* tags_; +}; diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp index 4d1589b50..fa23dccb0 100644 --- a/logd/fuzz/log_buffer_log_fuzzer.cpp +++ b/logd/fuzz/log_buffer_log_fuzzer.cpp @@ -94,7 +94,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } LastLogTimes times; - LogBuffer log_buffer(×); + LogTags tags; + LogBuffer log_buffer(×, &tags); size_t data_left = size; const uint8_t** pdata = &data; diff --git a/logd/main.cpp b/logd/main.cpp index 23bbf864d..87131472b 100644 --- a/logd/main.cpp +++ b/logd/main.cpp @@ -52,6 +52,7 @@ #include "LogBuffer.h" #include "LogKlog.h" #include "LogListener.h" +#include "LogTags.h" #include "LogUtils.h" #define KMSG_PRIORITY(PRI) \ @@ -355,6 +356,9 @@ int main(int argc, char* argv[]) { pthread_attr_destroy(&attr); } + // A cache of event log tags + LogTags log_tags; + // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. @@ -364,7 +368,7 @@ int main(int argc, char* argv[]) { // LogBuffer is the object which is responsible for holding all // log entries. - logBuf = new LogBuffer(times); + logBuf = new LogBuffer(times, &log_tags); signal(SIGHUP, reinit_signal_handler); @@ -396,7 +400,7 @@ int main(int argc, char* argv[]) { // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. - CommandListener* cl = new CommandListener(logBuf, reader, swl); + CommandListener* cl = new CommandListener(logBuf, &log_tags); if (cl->startListener()) { return EXIT_FAILURE; } From e170d1ac8d62670f03eee7d7b7ef9a055754bacc Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Fri, 1 May 2020 16:45:25 -0700 Subject: [PATCH 2/5] logd: don't use SIGHUP to reinitialize It doesn't look like there are any users, since there is a much better mechanism, `logd --reinit` that exists for this behavior. The settings app and init.rc use that mechanism and they are the two major clients that force logd to reinitialize. This saves us from creating a thread and marginally cleans up main.cpp. Test: log reinitialization works Change-Id: Icdb56b6f59adbba82812231a4f3a6ffd1a7955fc --- logd/CommandListener.cpp | 16 ++++++++- logd/CommandListener.h | 3 -- logd/LogBuffer.cpp | 6 +--- logd/LogTags.cpp | 17 ---------- logd/LogUtils.h | 6 +--- logd/main.cpp | 73 +--------------------------------------- 6 files changed, 18 insertions(+), 103 deletions(-) diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index 1e7a33a2d..4b940867b 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -296,7 +297,20 @@ int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/, char** /*argv*/) { setname(); - reinit_signal_handler(SIGHUP); + android::prdebug("logd reinit"); + buf()->init(); + buf()->initPrune(nullptr); + + // This only works on userdebug and eng devices to re-read the + // /data/misc/logd/event-log-tags file right after /data is mounted. + // The operation is near to boot and should only happen once. There + // are races associated with its use since it can trigger a Rebuild + // of the file, but that is a can-not-happen since the file was not + // read yet. More dangerous if called later, but if all is well it + // should just skip over everything and not write any new entries. + if (__android_log_is_debuggable()) { + tags()->ReadFileEventLogTags(tags()->debug_event_log_tags); + } cli->sendMsg("success"); diff --git a/logd/CommandListener.h b/logd/CommandListener.h index 80597b2a0..c50ab6e47 100644 --- a/logd/CommandListener.h +++ b/logd/CommandListener.h @@ -24,9 +24,6 @@ #include "LogReader.h" #include "LogTags.h" -// See main.cpp for implementation -void reinit_signal_handler(int /*signal*/); - class CommandListener : public FrameworkListener { public: CommandListener(LogBuffer* buf, LogTags* tags); diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 443fd980a..7e1bb0abc 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -92,11 +92,7 @@ void LogBuffer::init() { unlock(); } - // We may have been triggered by a SIGHUP. Release any sleeping reader - // threads to dump their current content. - // - // NB: this is _not_ performed in the context of a SIGHUP, it is - // performed during startup, and in context of reinit administrative thread + // Release any sleeping reader threads to dump their current content. LogTimeEntry::wrlock(); LastLogTimes::iterator times = mTimes.begin(); diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp index e45cc8ae6..3e52b3871 100644 --- a/logd/LogTags.cpp +++ b/logd/LogTags.cpp @@ -391,23 +391,6 @@ const char* android::tagToName(uint32_t tag) { return me->tagToName(tag); } -// Prototype in LogUtils.h allowing external access to our database. -// -// This only works on userdebug and eng devices to re-read the -// /data/misc/logd/event-log-tags file right after /data is mounted. -// The operation is near to boot and should only happen once. There -// are races associated with its use since it can trigger a Rebuild -// of the file, but that is a can-not-happen since the file was not -// read yet. More dangerous if called later, but if all is well it -// should just skip over everything and not write any new entries. -void android::ReReadEventLogTags() { - LogTags* me = logtags; - - if (me && __android_log_is_debuggable()) { - me->ReadFileEventLogTags(me->debug_event_log_tags); - } -} - // converts an event tag into a format const char* LogTags::tagToFormat(uint32_t tag) const { tag2format_const_iterator iform; diff --git a/logd/LogUtils.h b/logd/LogUtils.h index fa9f39895..f9cd42dcb 100644 --- a/logd/LogUtils.h +++ b/logd/LogUtils.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef _LOGD_LOG_UTILS_H__ -#define _LOGD_LOG_UTILS_H__ +#pragma once #include #include @@ -41,7 +40,6 @@ char* tidToName(pid_t tid); // Furnished in LogTags.cpp. Thread safe. const char* tagToName(uint32_t tag); -void ReReadEventLogTags(); // Furnished by LogKlog.cpp char* log_strntok_r(char* s, ssize_t& len, char*& saveptr, ssize_t& sublen); @@ -72,5 +70,3 @@ static inline bool worstUidEnabledForLogid(log_id_t id) { return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS); } - -#endif // _LOGD_LOG_UTILS_H__ diff --git a/logd/main.cpp b/logd/main.cpp index 87131472b..c4750ec3b 100644 --- a/logd/main.cpp +++ b/logd/main.cpp @@ -151,50 +151,6 @@ void android::prdebug(const char* fmt, ...) { } } -static sem_t reinit; -static bool reinit_running = false; -static LogBuffer* logBuf = nullptr; - -static void* reinit_thread_start(void* /*obj*/) { - prctl(PR_SET_NAME, "logd.daemon"); - - while (reinit_running && !sem_wait(&reinit) && reinit_running) { - if (fdDmesg >= 0) { - static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO), - 'l', - 'o', - 'g', - 'd', - '.', - 'd', - 'a', - 'e', - 'm', - 'o', - 'n', - ':', - ' ', - 'r', - 'e', - 'i', - 'n', - 'i', - 't', - '\n' }; - write(fdDmesg, reinit_message, sizeof(reinit_message)); - } - - // Anything that reads persist. - if (logBuf) { - logBuf->init(); - logBuf->initPrune(nullptr); - } - android::ReReadEventLogTags(); - } - - return nullptr; -} - char* android::uidToName(uid_t u) { struct Userdata { uid_t uid; @@ -221,12 +177,6 @@ char* android::uidToName(uid_t u) { return userdata.name; } -// Serves as a global method to trigger reinitialization -// and as a function that can be provided to signal(). -void reinit_signal_handler(int /*signal*/) { - sem_post(&reinit); -} - static void readDmesg(LogAudit* al, LogKlog* kl) { if (!al && !kl) { return; @@ -337,25 +287,6 @@ int main(int argc, char* argv[]) { return EXIT_FAILURE; } - // Reinit Thread - sem_init(&reinit, 0, 0); - pthread_attr_t attr; - if (!pthread_attr_init(&attr)) { - struct sched_param param; - - memset(¶m, 0, sizeof(param)); - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setschedpolicy(&attr, SCHED_BATCH); - if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { - pthread_t thread; - reinit_running = true; - if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) { - reinit_running = false; - } - } - pthread_attr_destroy(&attr); - } - // A cache of event log tags LogTags log_tags; @@ -368,9 +299,7 @@ int main(int argc, char* argv[]) { // LogBuffer is the object which is responsible for holding all // log entries. - logBuf = new LogBuffer(times, &log_tags); - - signal(SIGHUP, reinit_signal_handler); + LogBuffer* logBuf = new LogBuffer(times, &log_tags); if (__android_logger_property_get_bool( "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | From 5a3db391b4fe05dd599d89aec0fe01d61727fbcf Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Fri, 1 May 2020 17:03:20 -0700 Subject: [PATCH 3/5] logd: separate PruneList from LogBuffer logd needs a pointer to PruneList, but it should not own it and it should not have initPrune() or formatPrune() functions. Test: logging unit tests Change-Id: Id1668c26d07eb5d1e4cf267f5748c20a79f711ae --- logd/CommandListener.cpp | 10 +++++----- logd/CommandListener.h | 5 ++++- logd/LogBuffer.cpp | 21 ++++++++++++--------- logd/LogBuffer.h | 11 ++--------- logd/fuzz/log_buffer_log_fuzzer.cpp | 5 +++-- logd/main.cpp | 6 ++++-- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index 4b940867b..4044dc984 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp @@ -39,8 +39,8 @@ #include "LogCommand.h" #include "LogUtils.h" -CommandListener::CommandListener(LogBuffer* buf, LogTags* tags) - : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags) { +CommandListener::CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune) + : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags), prune_(prune) { registerCmd(new ClearCmd(this)); registerCmd(new GetBufSizeCmd(this)); registerCmd(new SetBufSizeCmd(this)); @@ -216,7 +216,7 @@ int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc, int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli, int /*argc*/, char** /*argv*/) { setname(); - cli->sendMsg(PackageString(buf()->formatPrune()).c_str()); + cli->sendMsg(PackageString(prune()->format()).c_str()); return 0; } @@ -236,7 +236,7 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc, str += argv[i]; } - int ret = buf()->initPrune(str.c_str()); + int ret = prune()->init(str.c_str()); if (ret) { cli->sendMsg("Invalid"); @@ -299,7 +299,7 @@ int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/, android::prdebug("logd reinit"); buf()->init(); - buf()->initPrune(nullptr); + prune()->init(nullptr); // This only works on userdebug and eng devices to re-read the // /data/misc/logd/event-log-tags file right after /data is mounted. diff --git a/logd/CommandListener.h b/logd/CommandListener.h index c50ab6e47..c90c247cb 100644 --- a/logd/CommandListener.h +++ b/logd/CommandListener.h @@ -23,10 +23,11 @@ #include "LogListener.h" #include "LogReader.h" #include "LogTags.h" +#include "LogWhiteBlackList.h" class CommandListener : public FrameworkListener { public: - CommandListener(LogBuffer* buf, LogTags* tags); + CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune); virtual ~CommandListener() {} private: @@ -34,6 +35,7 @@ class CommandListener : public FrameworkListener { LogBuffer* buf_; LogTags* tags_; + PruneList* prune_; #define LogCmd(name, command_string) \ class name##Cmd : public LogCommand { \ @@ -46,6 +48,7 @@ class CommandListener : public FrameworkListener { private: \ LogBuffer* buf() const { return parent_->buf_; } \ LogTags* tags() const { return parent_->tags_; } \ + PruneList* prune() const { return parent_->prune_; } \ CommandListener* parent_; \ } diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 7e1bb0abc..5c8a5f0aa 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -105,8 +105,11 @@ void LogBuffer::init() { LogTimeEntry::unlock(); } -LogBuffer::LogBuffer(LastLogTimes* times, LogTags* tags) - : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times), tags_(tags) { +LogBuffer::LogBuffer(LastLogTimes* times, LogTags* tags, PruneList* prune) + : monotonic(android_log_clockid() == CLOCK_MONOTONIC), + mTimes(*times), + tags_(tags), + prune_(prune) { pthread_rwlock_init(&mLogElementsLock, nullptr); log_id_for_each(i) { @@ -694,7 +697,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } // prune by worst offenders; by blacklist, UID, and by PID of system UID - bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty(); + bool hasBlacklist = (id != LOG_ID_SECURITY) && prune_->naughty(); while (!clearAll && (pruneRows > 0)) { // recalculate the worst offender on every batched pass int worst = -1; // not valid for getUid() or getKey() @@ -702,7 +705,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { size_t second_worst_sizes = 0; pid_t worstPid = 0; // POSIX guarantees PID != 0 - if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) { + if (worstUidEnabledForLogid(id) && prune_->worstUidEnabled()) { // Calculate threshold as 12.5% of available storage size_t threshold = log_buffer_size(id) / 8; @@ -716,7 +719,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { .findWorst(worst, worst_sizes, second_worst_sizes, threshold); - if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) { + if ((worst == AID_SYSTEM) && prune_->worstPidOfSystemEnabled()) { stats.sortPids(worst, (pid_t)0, 2, id) .findWorst(worstPid, worst_sizes, second_worst_sizes); } @@ -798,7 +801,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { ? element->getTag() : element->getUid(); - if (hasBlacklist && mPrune.naughty(element)) { + if (hasBlacklist && prune_->naughty(element)) { last.clear(element); it = erase(it); if (dropped) { @@ -895,13 +898,13 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { } last.clear(); - if (!kick || !mPrune.worstUidEnabled()) { + if (!kick || !prune_->worstUidEnabled()) { break; // the following loop will ask bad clients to skip/drop } } bool whitelist = false; - bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll; + bool hasWhitelist = (id != LOG_ID_SECURITY) && prune_->nice() && !clearAll; it = GetOldest(id); while ((pruneRows > 0) && (it != mLogElements.end())) { LogBufferElement* element = *it; @@ -917,7 +920,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { break; } - if (hasWhitelist && !element->getDropped() && mPrune.nice(element)) { + if (hasWhitelist && !element->getDropped() && prune_->nice(element)) { // WhiteListed whitelist = true; it++; diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index b8e64d03b..cf93c23ae 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -80,7 +80,6 @@ class LogBuffer { LogStatistics stats; - PruneList mPrune; // Keeps track of the iterator to the oldest log message of a given log type, as an // optimization when pruning logs. Use GetOldest() to retrieve. std::optional mOldest[LOG_ID_MAX]; @@ -104,7 +103,7 @@ class LogBuffer { public: LastLogTimes& mTimes; - LogBuffer(LastLogTimes* times, LogTags* tags); + LogBuffer(LastLogTimes* times, LogTags* tags, PruneList* prune); ~LogBuffer(); void init(); bool isMonotonic() { @@ -133,13 +132,6 @@ class LogBuffer { stats.enableStatistics(); } - int initPrune(const char* cp) { - return mPrune.init(cp); - } - std::string formatPrune() { - return mPrune.format(); - } - // helper must be protected directly or implicitly by wrlock()/unlock() const char* pidToName(pid_t pid) { return stats.pidToName(pid); @@ -174,4 +166,5 @@ class LogBuffer { LogBufferElementCollection::iterator GetOldest(log_id_t log_id); LogTags* tags_; + PruneList* prune_; }; diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp index fa23dccb0..14c5163e2 100644 --- a/logd/fuzz/log_buffer_log_fuzzer.cpp +++ b/logd/fuzz/log_buffer_log_fuzzer.cpp @@ -95,12 +95,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { LastLogTimes times; LogTags tags; - LogBuffer log_buffer(×, &tags); + PruneList prune_list; + LogBuffer log_buffer(×, &tags, &prune_list); size_t data_left = size; const uint8_t** pdata = &data; log_buffer.enableStatistics(); - log_buffer.initPrune(nullptr); + prune_list.init(nullptr); // We want to get pruning code to get called. log_id_for_each(i) { log_buffer.setSize(i, 10000); } diff --git a/logd/main.cpp b/logd/main.cpp index c4750ec3b..cc45eb3f3 100644 --- a/logd/main.cpp +++ b/logd/main.cpp @@ -289,6 +289,8 @@ int main(int argc, char* argv[]) { // A cache of event log tags LogTags log_tags; + // Pruning configuration. + PruneList prune_list; // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log @@ -299,7 +301,7 @@ int main(int argc, char* argv[]) { // LogBuffer is the object which is responsible for holding all // log entries. - LogBuffer* logBuf = new LogBuffer(times, &log_tags); + LogBuffer* logBuf = new LogBuffer(times, &log_tags, &prune_list); if (__android_logger_property_get_bool( "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | @@ -329,7 +331,7 @@ int main(int argc, char* argv[]) { // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. - CommandListener* cl = new CommandListener(logBuf, &log_tags); + CommandListener* cl = new CommandListener(logBuf, &log_tags, &prune_list); if (cl->startListener()) { return EXIT_FAILURE; } From 20118eec696763f128401cb8c4c57a5d137d00c1 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 4 May 2020 10:17:42 -0700 Subject: [PATCH 4/5] logd: rename mOldest -> oldest_ I added mOldest recently before mentally committing to have new code follow the Google C++ style guide. Test: build Change-Id: I6d5bab5833e14ac3808862598a2a60989d805e18 --- logd/LogBuffer.cpp | 12 ++++++------ logd/LogBuffer.h | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 5c8a5f0aa..a3e4e094e 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -129,14 +129,14 @@ LogBuffer::~LogBuffer() { LogBufferElementCollection::iterator LogBuffer::GetOldest(log_id_t log_id) { auto it = mLogElements.begin(); - if (mOldest[log_id]) { - it = *mOldest[log_id]; + if (oldest_[log_id]) { + it = *oldest_[log_id]; } while (it != mLogElements.end() && (*it)->getLogId() != log_id) { it++; } if (it != mLogElements.end()) { - mOldest[log_id] = it; + oldest_[log_id] = it; } return it; } @@ -460,7 +460,7 @@ LogBufferElementCollection::iterator LogBuffer::erase( bool setLast[LOG_ID_MAX]; bool doSetLast = false; - log_id_for_each(i) { doSetLast |= setLast[i] = mOldest[i] && it == *mOldest[i]; } + log_id_for_each(i) { doSetLast |= setLast[i] = oldest_[i] && it == *oldest_[i]; } #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES LogBufferElementCollection::iterator bad = it; int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) @@ -472,9 +472,9 @@ LogBufferElementCollection::iterator LogBuffer::erase( log_id_for_each(i) { if (setLast[i]) { if (__predict_false(it == mLogElements.end())) { - mOldest[i] = std::nullopt; + oldest_[i] = std::nullopt; } else { - mOldest[i] = it; // Store the next iterator even if it does not correspond to + oldest_[i] = it; // Store the next iterator even if it does not correspond to // the same log_id, as a starting point for GetOldest(). } } diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index cf93c23ae..9a367127a 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -80,9 +80,6 @@ class LogBuffer { LogStatistics stats; - // Keeps track of the iterator to the oldest log message of a given log type, as an - // optimization when pruning logs. Use GetOldest() to retrieve. - std::optional mOldest[LOG_ID_MAX]; // watermark of any worst/chatty uid processing typedef std::unordered_map LogBufferIteratorMap; @@ -167,4 +164,8 @@ class LogBuffer { LogTags* tags_; PruneList* prune_; + + // Keeps track of the iterator to the oldest log message of a given log type, as an + // optimization when pruning logs. Use GetOldest() to retrieve. + std::optional oldest_[LOG_ID_MAX]; }; From 79d54f7877ccb6c45d5c9be059c459f93fde1836 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 4 May 2020 11:13:55 -0700 Subject: [PATCH 5/5] logd: remove FlushCommand This code has evolved to the point that it LogReader::notifyNewLog() executes FlushCommand on every socket. FlushCommand then iterates over all log reader threads in LogTimes and flushes triggers them to flush logs if they match the client. This can be simplified to simply looping over all of the reads in LogTimes. Code readability was the primary motivation here, but note that 64% of LogReader::notifyNewLog() was spent looping over the sockets, and an additional 78% of FlushCommand::runSocketCommand() was spent repeatedly locking and unlocking the LogTimes lock. Overall, this reduces the cost of LogReader::notifyNewLog() in LogListener::onDataAvailable() from 5.91% to 2.93%. This is the critical path for handling incoming log messages, so it's a non-trivial savings. Test: logging unit tests Test: unprivileged clients still cannot view privileged logs Change-Id: Ic7620978a6c23e5e2cb179ff0c42b7cea52fc011 --- logd/Android.bp | 1 - logd/FlushCommand.cpp | 75 ------------------------------------------- logd/FlushCommand.h | 43 ------------------------- logd/LogReader.cpp | 30 +++++++++++++---- logd/LogTimes.cpp | 17 +++++----- logd/LogTimes.h | 6 +++- 6 files changed, 36 insertions(+), 136 deletions(-) delete mode 100644 logd/FlushCommand.cpp delete mode 100644 logd/FlushCommand.h diff --git a/logd/Android.bp b/logd/Android.bp index b337b7c2a..26632713d 100644 --- a/logd/Android.bp +++ b/logd/Android.bp @@ -36,7 +36,6 @@ cc_library_static { "CommandListener.cpp", "LogListener.cpp", "LogReader.cpp", - "FlushCommand.cpp", "LogBuffer.cpp", "LogBufferElement.cpp", "LogTimes.cpp", diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp deleted file mode 100644 index 0845504ac..000000000 --- a/logd/FlushCommand.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012-2014 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 - -#include - -#include "FlushCommand.h" -#include "LogBuffer.h" -#include "LogBufferElement.h" -#include "LogCommand.h" -#include "LogReader.h" -#include "LogTimes.h" -#include "LogUtils.h" - -// runSocketCommand is called once for every open client on the -// log reader socket. Here we manage and associated the reader -// client tracking and log region locks LastLogTimes list of -// LogTimeEntrys, and spawn a transitory per-client thread to -// work at filing data to the socket. -// -// global LogTimeEntry::wrlock() is used to protect access, -// reference counts are used to ensure that individual -// LogTimeEntry lifetime is managed when not protected. -void FlushCommand::runSocketCommand(SocketClient* client) { - LogTimeEntry* entry = nullptr; - LastLogTimes& times = mReader.logbuf().mTimes; - - LogTimeEntry::wrlock(); - LastLogTimes::iterator it = times.begin(); - while (it != times.end()) { - entry = it->get(); - if (entry->mClient == client) { - if (!entry->isWatchingMultiple(mLogMask)) { - LogTimeEntry::unlock(); - return; - } - if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) { - LogTimeEntry::unlock(); - return; - } - entry->triggerReader_Locked(); - LogTimeEntry::unlock(); - return; - } - it++; - } - - LogTimeEntry::unlock(); -} - -bool FlushCommand::hasReadLogs(SocketClient* client) { - return clientHasLogCredentials(client); -} - -static bool clientHasSecurityCredentials(SocketClient* client) { - return (client->getUid() == AID_SYSTEM) || (client->getGid() == AID_SYSTEM); -} - -bool FlushCommand::hasSecurityLogs(SocketClient* client) { - return clientHasSecurityCredentials(client); -} diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h deleted file mode 100644 index a69d43922..000000000 --- a/logd/FlushCommand.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2012-2013 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 _FLUSH_COMMAND_H -#define _FLUSH_COMMAND_H - -#include -#include - -class LogBufferElement; - -#include "LogTimes.h" - -class LogReader; - -class FlushCommand : public SocketClientCommand { - LogReader& mReader; - log_mask_t mLogMask; - - public: - explicit FlushCommand(LogReader& reader, log_mask_t logMask) - : mReader(reader), mLogMask(logMask) { - } - - virtual void runSocketCommand(SocketClient* client); - - static bool hasReadLogs(SocketClient* client); - static bool hasSecurityLogs(SocketClient* client); -}; - -#endif diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp index f79d39c9d..c6dea69f8 100644 --- a/logd/LogReader.cpp +++ b/logd/LogReader.cpp @@ -24,21 +24,35 @@ #include #include -#include "FlushCommand.h" #include "LogBuffer.h" #include "LogBufferElement.h" #include "LogReader.h" #include "LogUtils.h" +static bool CanReadSecurityLogs(SocketClient* client) { + return client->getUid() == AID_SYSTEM || client->getGid() == AID_SYSTEM; +} + LogReader::LogReader(LogBuffer* logbuf) : SocketListener(getLogSocket(), true), mLogbuf(*logbuf) { } // When we are notified a new log entry is available, inform // listening sockets who are watching this entry's log id. -void LogReader::notifyNewLog(log_mask_t logMask) { - FlushCommand command(*this, logMask); - runOnEachSocket(&command); +void LogReader::notifyNewLog(log_mask_t log_mask) { + LastLogTimes& times = mLogbuf.mTimes; + + LogTimeEntry::wrlock(); + for (const auto& entry : times) { + if (!entry->isWatchingMultiple(log_mask)) { + continue; + } + if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) { + continue; + } + entry->triggerReader_Locked(); + } + LogTimeEntry::unlock(); } // Note returning false will release the SocketClient instance. @@ -129,6 +143,9 @@ bool LogReader::onDataAvailable(SocketClient* cli) { nonBlock = true; } + bool privileged = clientHasLogCredentials(cli); + bool can_read_security = CanReadSecurityLogs(cli); + uint64_t sequence = 1; // Convert realtime to sequence number if (start != log_time::EPOCH) { @@ -178,8 +195,7 @@ bool LogReader::onDataAvailable(SocketClient* cli) { } logFindStart(logMask, pid, start, sequence, logbuf().isMonotonic() && android::isMonotonic(start)); - logbuf().flushTo(cli, sequence, nullptr, FlushCommand::hasReadLogs(cli), - FlushCommand::hasSecurityLogs(cli), + logbuf().flushTo(cli, sequence, nullptr, privileged, can_read_security, logFindStart.callback, &logFindStart); if (!logFindStart.found()) { @@ -203,7 +219,7 @@ bool LogReader::onDataAvailable(SocketClient* cli) { LogTimeEntry::wrlock(); auto entry = std::make_unique(*this, cli, nonBlock, tail, logMask, pid, start, - sequence, timeout); + sequence, timeout, privileged, can_read_security); if (!entry->startReader_Locked()) { LogTimeEntry::unlock(); return false; diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp index ed8d2f527..ad150bdb6 100644 --- a/logd/LogTimes.cpp +++ b/logd/LogTimes.cpp @@ -18,7 +18,6 @@ #include #include -#include "FlushCommand.h" #include "LogBuffer.h" #include "LogReader.h" #include "LogTimes.h" @@ -27,7 +26,8 @@ pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER; LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock, unsigned long tail, log_mask_t logMask, pid_t pid, log_time start_time, - uint64_t start, uint64_t timeout) + uint64_t start, uint64_t timeout, bool privileged, + bool can_read_security_logs) : leadingDropped(false), mReader(reader), mLogMask(logMask), @@ -38,7 +38,9 @@ LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBloc mClient(client), mStartTime(start_time), mStart(start), - mNonBlock(nonBlock) { + mNonBlock(nonBlock), + privileged_(privileged), + can_read_security_logs_(can_read_security_logs) { mTimeout.tv_sec = timeout / NS_PER_SEC; mTimeout.tv_nsec = timeout % NS_PER_SEC; memset(mLastTid, 0, sizeof(mLastTid)); @@ -72,9 +74,6 @@ void* LogTimeEntry::threadStart(void* obj) { LogBuffer& logbuf = me->mReader.logbuf(); - bool privileged = FlushCommand::hasReadLogs(client); - bool security = FlushCommand::hasSecurityLogs(client); - me->leadingDropped = true; wrlock(); @@ -96,12 +95,12 @@ void* LogTimeEntry::threadStart(void* obj) { unlock(); if (me->mTail) { - logbuf.flushTo(client, start, nullptr, privileged, security, + logbuf.flushTo(client, start, nullptr, me->privileged_, me->can_read_security_logs_, FilterFirstPass, me); me->leadingDropped = true; } - start = logbuf.flushTo(client, start, me->mLastTid, privileged, - security, FilterSecondPass, me); + start = logbuf.flushTo(client, start, me->mLastTid, me->privileged_, + me->can_read_security_logs_, FilterSecondPass, me); // We only ignore entries before the original start time for the first flushTo(), if we // get entries after this first flush before the original start time, then the client diff --git a/logd/LogTimes.h b/logd/LogTimes.h index a99c73bc6..56c930a15 100644 --- a/logd/LogTimes.h +++ b/logd/LogTimes.h @@ -52,7 +52,7 @@ class LogTimeEntry { public: LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock, unsigned long tail, log_mask_t logMask, pid_t pid, log_time start_time, uint64_t sequence, - uint64_t timeout); + uint64_t timeout, bool privileged, bool can_read_security_logs); SocketClient* mClient; log_time mStartTime; @@ -98,6 +98,10 @@ class LogTimeEntry { // flushTo filter callbacks static int FilterFirstPass(const LogBufferElement* element, void* me); static int FilterSecondPass(const LogBufferElement* element, void* me); + + private: + bool privileged_; + bool can_read_security_logs_; }; typedef std::list> LastLogTimes;