diff --git a/liblog/Android.mk b/liblog/Android.mk index a183db83e..4ab5006e2 100644 --- a/liblog/Android.mk +++ b/liblog/Android.mk @@ -22,7 +22,7 @@ include $(CLEAR_VARS) # '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 c2b0ec2ea..ec86e6ba2 100644 --- a/liblog/logd_write.c +++ b/liblog/logd_write.c @@ -39,6 +39,7 @@ #include #endif +#include #include #include #include @@ -71,6 +72,11 @@ static void lock() 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 @@ static void unlock() #else /* !defined(_WIN32) */ #define lock() ((void)0) +#define trylock() (0) /* success */ #define unlock() ((void)0) #endif /* !defined(_WIN32) */ @@ -194,6 +201,9 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) 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 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) } } 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 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) } } 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 feca8d555..d19c2552b 100644 --- a/logd/Android.mk +++ b/logd/Android.mk @@ -38,7 +38,9 @@ LOCAL_SHARED_LIBRARIES := \ # 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 ec323934b..1b829c602 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -205,16 +205,20 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, 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);