logd: iterator corruption paranoia
(cherry pick from commit 3614a0c5d4aec84fbc5f6cbf1e919e8b3825b818)
Add checking for impossible(tm) scenarios within LogBuffer::flushTo:
1) When iterating through the log entries, check if the iterator
returns two identical element references and break out of the loop.
2) Cap the maximum number of log entries we will skip while holding
the iterator lock at 4194304, break out of the loop.
We print a message to the kernel logs if we hit these cases.
ToDo: Remove this paranoia at some future date.
Test: gTest liblog-unit-tests logcat-unit-tests and logd-unit-tests
Bug: 37378309
Change-Id: I789594649db14093238828b9f6d1daeca8b780c2
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1eda15d..4aa2c9f 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -1120,9 +1120,22 @@
log_time max = start;
+ LogBufferElement* lastElement = nullptr; // iterator corruption paranoia
+ static const size_t maxSkip = 4194304; // maximum entries to skip
+ size_t skip = maxSkip;
for (; it != mLogElements.end(); ++it) {
LogBufferElement* element = *it;
+ if (!--skip) {
+ android::prdebug("reader.per: too many elements skipped");
+ break;
+ }
+ if (element == lastElement) {
+ android::prdebug("reader.per: identical elements");
+ break;
+ }
+ lastElement = element;
+
if (!privileged && (element->getUid() != uid)) {
continue;
}
@@ -1167,6 +1180,7 @@
return max;
}
+ skip = maxSkip;
pthread_mutex_lock(&mLogElementsLock);
}
pthread_mutex_unlock(&mLogElementsLock);