Fix overflow for long Trusty logs am: caa341e88d Original change: https://android-review.googlesource.com/c/platform/system/logging/+/2008213 Change-Id: Iae03bd9c9952f2e860c346d1a48798e8840afc50
diff --git a/logd/TrustyLog.cpp b/logd/TrustyLog.cpp index 83ecc4c..213533d 100644 --- a/logd/TrustyLog.cpp +++ b/logd/TrustyLog.cpp
@@ -43,9 +43,35 @@ } } +/* + * Log a message, breaking it into smaller chunks if needed + */ +void TrustyLog::LogMsg(const char* msg, size_t len) { + char linebuffer[TRUSTY_LINE_BUFFER_SIZE + sizeof(trustyprefix) + 1]; + + while (len) { + size_t sublen = len; + if (sublen > TRUSTY_LINE_BUFFER_SIZE) { + sublen = TRUSTY_LINE_BUFFER_SIZE; + } + + *linebuffer = ANDROID_LOG_INFO; + strcpy(linebuffer + 1, trustyprefix); + strncpy(linebuffer + 1 + sizeof(trustyprefix), msg, sublen); + timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + log_time now = log_time(tp.tv_sec, tp.tv_nsec); + // The Log() API appears to want a length that is 1 greater than what's + // actually being logged. + logbuf->Log(LOG_ID_KERNEL, now, AID_ROOT, 0 /*pid*/, 0 /*tid*/, linebuffer, + sizeof(trustyprefix) + sublen + 2); + msg += sublen; + len -= sublen; + } +} + bool TrustyLog::onDataAvailable(SocketClient* cli) { char buffer[4096]; - char linebuffer[TRUSTY_LINE_BUFFER_SIZE + sizeof(trustyprefix) + 1]; ssize_t len = 0; for (;;) { ssize_t retval = 0; @@ -66,17 +92,16 @@ for (;;) { char* lineend = static_cast<char*>(memchr(linestart, '\n', len)); if (lineend) { - size_t linelen = lineend - linestart + 1; - *linebuffer = ANDROID_LOG_INFO; - strcpy(linebuffer + 1, trustyprefix); - strncpy(linebuffer + 1 + sizeof(trustyprefix), linestart, linelen - 1); - timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); - log_time now = log_time(tp.tv_sec, tp.tv_nsec); - logbuf->Log(LOG_ID_KERNEL, now, AID_ROOT, 0 /*pid*/, 0 /*tid*/, linebuffer, - sizeof(trustyprefix) + linelen + 1); - linestart += linelen; - len -= linelen; + // print one newline-terminated line + size_t linelen = lineend - linestart; + LogMsg(linestart, linelen); + linestart += (linelen + 1); // next line, skipping the newline + len -= (linelen + 1); + } else if (len >= TRUSTY_LINE_BUFFER_SIZE) { + // there was no newline, but there's enough data to print + LogMsg(linestart, TRUSTY_LINE_BUFFER_SIZE); + linestart += TRUSTY_LINE_BUFFER_SIZE; + len -= TRUSTY_LINE_BUFFER_SIZE; } else { if (len) { // there's some unterminated data left at the end of the
diff --git a/logd/TrustyLog.h b/logd/TrustyLog.h index 0463509..c9960ec 100644 --- a/logd/TrustyLog.h +++ b/logd/TrustyLog.h
@@ -28,6 +28,7 @@ */ class TrustyLog : public SocketListener { LogBuffer* logbuf; + void LogMsg(const char* msg, size_t len); public: static void create(LogBuffer* buf);