Merge changes Ibdc76bc0,I98738c66

* changes:
  logd: liblog: whitelist "snet_event_log"
  liblog: add __android_log_is_loggable checking to writer
diff --git a/liblog/Android.mk b/liblog/Android.mk
index a183db8..4ab5006 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -22,7 +22,7 @@
 #       's/^\([0-9]*\)[ \t]*liblog[ \t].*/-DLIBLOG_LOG_TAG=\1/p' \
 #       $(LOCAL_PATH)/event.logtags)
 # so make sure we do not regret hard-coding it as follows:
-liblog_cflags := -DLIBLOG_LOG_TAG=1005
+liblog_cflags := -DLIBLOG_LOG_TAG=1005 -DSNET_EVENT_LOG_TAG=1397638484
 
 liblog_host_sources := logd_write.c log_event_write.c fake_log_device.c event.logtags
 liblog_target_sources := logd_write.c log_event_write.c event_tag_map.c log_time.cpp log_is_loggable.c
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index c2b0ec2..ec86e6b 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -39,6 +39,7 @@
 #include <android/set_abort_message.h>
 #endif
 
+#include <log/event_tag_map.h>
 #include <log/logd.h>
 #include <log/logger.h>
 #include <log/log_read.h>
@@ -71,6 +72,11 @@
     pthread_mutex_lock(&log_init_lock);
 }
 
+static int trylock()
+{
+    return pthread_mutex_trylock(&log_init_lock);
+}
+
 static void unlock()
 {
     pthread_mutex_unlock(&log_init_lock);
@@ -79,6 +85,7 @@
 #else   /* !defined(_WIN32) */
 
 #define lock() ((void)0)
+#define trylock() (0) /* success */
 #define unlock() ((void)0)
 
 #endif  /* !defined(_WIN32) */
@@ -194,6 +201,9 @@
         last_pid = getpid();
     }
     if (log_id == LOG_ID_SECURITY) {
+        if (vec[0].iov_len < 4) {
+            return -EINVAL;
+        }
         if ((last_uid != AID_SYSTEM) && (last_uid != AID_ROOT)) {
             uid_t uid = geteuid();
             if ((uid != AID_SYSTEM) && (uid != AID_ROOT)) {
@@ -207,9 +217,84 @@
             }
         }
         if (!__android_log_security()) {
+            atomic_store(&dropped_security, 0);
+            return -EPERM;
+        }
+    } else if (log_id == LOG_ID_EVENTS) {
+        if (vec[0].iov_len < 4) {
+            return -EINVAL;
+        }
+        if (((uint32_t *)vec[0].iov_base)[0] != htole32(SNET_EVENT_LOG_TAG)) {
+            static atomic_uintptr_t map;
+            int ret;
+            const char *tag = NULL;
+            EventTagMap *m, *f = NULL;
+
+            m = (EventTagMap *)atomic_load(&map);
+            if (!m) {
+                ret = trylock();
+                m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */
+                if (!m) {
+                    m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+                    if (ret) { /* trylock failed, local copy, mark for close */
+                        f = m;
+                    } else {
+                        if (!m) { /* One chance to open map file */
+                            m = (EventTagMap *)(uintptr_t)-1LL;
+                        }
+                        atomic_store(&map, (uintptr_t)m);
+                    }
+                }
+                if (!ret) { /* trylock succeeded, unlock */
+                    unlock();
+                }
+            }
+            if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
+                tag = android_lookupEventTag(
+                                    m,
+                                    htole32(((uint32_t *)vec[0].iov_base)[0]));
+            }
+            ret = __android_log_is_loggable(ANDROID_LOG_INFO,
+                                            tag,
+                                            ANDROID_LOG_VERBOSE);
+            if (f) { /* local copy marked for close */
+                android_closeEventTagMap(f);
+            }
+            if (!ret) {
+                return -EPERM;
+            }
+        }
+    } else {
+        /* Validate the incoming tag, tag content can not split across iovec */
+        char prio = ANDROID_LOG_VERBOSE;
+        const char *tag = vec[0].iov_base;
+        size_t len = vec[0].iov_len;
+        if (!tag) {
+            len = 0;
+        }
+        if (len > 0) {
+            prio = *tag;
+            if (len > 1) {
+                --len;
+                ++tag;
+            } else {
+                len = vec[1].iov_len;
+                tag = ((const char *)vec[1].iov_base);
+                if (!tag) {
+                    len = 0;
+                }
+            }
+        }
+        /* tag must be nul terminated */
+        if (strnlen(tag, len) >= len) {
+            tag = NULL;
+        }
+
+        if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
             return -EPERM;
         }
     }
+
     /*
      *  struct {
      *      // what we provide to pstore
@@ -267,7 +352,9 @@
             }
         }
         snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
-        if (snapshot) {
+        if (snapshot && __android_log_is_loggable(ANDROID_LOG_INFO,
+                                                  "liblog",
+                                                  ANDROID_LOG_VERBOSE)) {
             android_log_event_int_t buffer;
 
             header.id = LOG_ID_EVENTS;
diff --git a/logd/Android.mk b/logd/Android.mk
index feca8d5..d19c255 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -38,7 +38,9 @@
 #  event_flag := $(call event_logtags,auditd)
 #  event_flag += $(call event_logtags,logd)
 # so make sure we do not regret hard-coding it as follows:
-event_flag := -DAUDITD_LOG_TAG=1003 -DLOGD_LOG_TAG=1004
+event_flag := -DAUDITD_LOG_TAG=1003 \
+              -DLOGD_LOG_TAG=1004 \
+              -DSNET_EVENT_LOG_TAG=1397638484
 
 LOCAL_CFLAGS := -Werror $(event_flag)
 
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index ec32393..1b829c6 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -205,16 +205,20 @@
 
     LogBufferElement *elem = new LogBufferElement(log_id, realtime,
                                                   uid, pid, tid, msg, len);
-    if (log_id != LOG_ID_SECURITY) {
+    if (log_id != LOG_ID_SECURITY) { // whitelist LOG_ID_SECURITY
         int prio = ANDROID_LOG_INFO;
-        const char *tag = NULL;
+        const char *tag = (const char *)-1;
         if (log_id == LOG_ID_EVENTS) {
-            tag = android::tagToName(elem->getTag());
+            // whitelist "snet_event_log"
+            if (elem->getTag() != SNET_EVENT_LOG_TAG) {
+                tag = android::tagToName(elem->getTag());
+            }
         } else {
             prio = *msg;
             tag = msg + 1;
         }
-        if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
+        if ((tag != (const char *)-1) &&
+                !__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
             // Log traffic received to total
             pthread_mutex_lock(&mLogElementsLock);
             stats.add(elem);