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