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; }