Snap for 8720775 from b2ca6f29c64e8efd11cee852562a4054368dcf81 to mainline-sdkext-release

Change-Id: I6685401e78e5ccee306047c7da037ff507020ca1
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index 08ab6e2..9a9a126 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -60,7 +60,7 @@
 static int check_log_uid_permissions() {
   uid_t uid = getuid();
 
-  /* Matches clientHasLogCredentials() in logd */
+  /* Matches clientCanWriteSecurityLog() in logd */
   if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
     uid = geteuid();
     if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
@@ -81,7 +81,8 @@
           }
           num_groups = getgroups(num_groups, groups);
           while (num_groups > 0) {
-            if (groups[num_groups - 1] == AID_LOG) {
+            if (groups[num_groups - 1] == AID_LOG ||
+                groups[num_groups - 1] == AID_SECURITY_LOG_WRITER) {
               break;
             }
             --num_groups;
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index ae74796..182567d 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -103,10 +103,13 @@
         return;
     }
 
-    if ((logId == LOG_ID_SECURITY) &&
-        (!__android_log_security() ||
-         !clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) {
-        return;
+    if (logId == LOG_ID_SECURITY) {
+        if (!__android_log_security()) {
+            return;
+        }
+        if (!clientCanWriteSecurityLog(cred->uid, cred->gid, cred->pid)) {
+            return;
+        }
     }
 
     char* msg = ((char*)buffer) + sizeof(android_log_header_t);
diff --git a/logd/LogPermissions.cpp b/logd/LogPermissions.cpp
index 31e145a..b8b0bd0 100644
--- a/logd/LogPermissions.cpp
+++ b/logd/LogPermissions.cpp
@@ -26,7 +26,7 @@
 
 #include <private/android_filesystem_config.h>
 
-static bool groupIsLog(char* buf) {
+static bool checkGroup(char* buf, gid_t gidToCheck) {
     char* ptr;
     static const char ws[] = " \n";
 
@@ -36,7 +36,7 @@
         if (errno != 0) {
             return false;
         }
-        if (Gid == AID_LOG) {
+        if (Gid == gidToCheck) {
             return true;
         }
     }
@@ -54,17 +54,12 @@
 // This function introduces races especially since status
 // can change 'shape' while reading, the net result is err
 // on lack of permission.
-bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) {
-    if (UserIsPrivileged(uid) || UserIsPrivileged(gid)) {
-        return true;
-    }
-
-    // FYI We will typically be here for 'adb logcat'
+static bool checkSupplementaryGroup(uid_t uid, gid_t gid, pid_t pid, gid_t gidToCheck) {
     char filename[256];
     snprintf(filename, sizeof(filename), "/proc/%u/status", pid);
 
     bool ret;
-    bool foundLog = false;
+    bool foundGroup = false;
     bool foundGid = false;
     bool foundUid = false;
 
@@ -83,8 +78,7 @@
     // doubt, but we expect the falses  should be reduced significantly as
     // three times is a charm.
     //
-    for (int retry = 3; !(ret = foundGid && foundUid && foundLog) && retry;
-         --retry) {
+    for (int retry = 3; !(ret = foundGid && foundUid && foundGroup) && retry; --retry) {
         FILE* file = fopen(filename, "re");
         if (!file) {
             continue;
@@ -98,8 +92,8 @@
             static const char gid_string[] = "Gid:\t";
 
             if (strncmp(groups_string, line, sizeof(groups_string) - 1) == 0) {
-                if (groupIsLog(line + sizeof(groups_string) - 1)) {
-                    foundLog = true;
+                if (checkGroup(line + sizeof(groups_string) - 1, gidToCheck)) {
+                    foundGroup = true;
                 }
             } else if (strncmp(uid_string, line, sizeof(uid_string) - 1) == 0) {
                 uid_t u[4] = { (uid_t)-1, (uid_t)-1, (uid_t)-1, (uid_t)-1 };
@@ -132,6 +126,22 @@
     return ret;
 }
 
+bool clientCanWriteSecurityLog(uid_t uid, gid_t gid, pid_t pid) {
+    if (UserIsPrivileged(uid) || UserIsPrivileged(gid)) {
+        return true;
+    }
+    return checkSupplementaryGroup(uid, gid, pid, AID_SECURITY_LOG_WRITER) ||
+           checkSupplementaryGroup(uid, gid, pid, AID_LOG);
+}
+
+bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) {
+    if (UserIsPrivileged(uid) || UserIsPrivileged(gid)) {
+        return true;
+    }
+    // FYI We will typically be here for 'adb logcat'
+    return checkSupplementaryGroup(uid, gid, pid, AID_LOG);
+}
+
 bool clientHasLogCredentials(SocketClient* cli) {
     if (UserIsPrivileged(cli->getUid()) || UserIsPrivileged(cli->getGid())) {
         return true;
diff --git a/logd/LogPermissions.h b/logd/LogPermissions.h
index 7065d9f..34a8607 100644
--- a/logd/LogPermissions.h
+++ b/logd/LogPermissions.h
@@ -22,4 +22,5 @@
 
 bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid);
 bool clientHasLogCredentials(SocketClient* cli);
+bool clientCanWriteSecurityLog(uid_t uid, gid_t gid, pid_t pid);
 bool clientIsExemptedFromUserConsent(SocketClient* cli);
diff --git a/logd/TrustyLog.cpp b/logd/TrustyLog.cpp
index 213533d..b04587a 100644
--- a/logd/TrustyLog.cpp
+++ b/logd/TrustyLog.cpp
@@ -73,6 +73,7 @@
 bool TrustyLog::onDataAvailable(SocketClient* cli) {
     char buffer[4096];
     ssize_t len = 0;
+    bool need_newline = false;
     for (;;) {
         ssize_t retval = 0;
         if (len < (ssize_t)(sizeof(buffer) - 1)) {
@@ -104,10 +105,17 @@
                 len -= TRUSTY_LINE_BUFFER_SIZE;
             } else {
                 if (len) {
+                    if (need_newline) {
+                        // still no newline after reading more, log what we have
+                        // and return
+                        LogMsg(linestart, len);
+                        return true;
+                    }
                     // there's some unterminated data left at the end of the
                     // buffer. Move it to the front and try to append more in
                     // the outer loop.
                     memmove(buffer, linestart, len);
+                    need_newline = true;
                 }
                 break;
             }
diff --git a/logd/main.cpp b/logd/main.cpp
index e405544..f8be2dc 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -307,6 +307,8 @@
         delete al;
     }
 
+    TrustyLog::create(log_buffer);
+
     TEMP_FAILURE_RETRY(pause());
 
     return EXIT_SUCCESS;