Loading include/log/log.h +2 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,8 @@ typedef enum log_id { */ int __android_log_is_loggable(int prio, const char *tag, int default_prio); int __android_log_security(); /* Device Owner is present */ int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data, uint32_t dataLen); Loading liblog/log_is_loggable.c +48 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ struct cache { char c; }; #define BOOLEAN_TRUE 0xFF #define BOOLEAN_FALSE 0xFE static void refresh_cache(struct cache *cache, const char *key) { uint32_t serial; Loading @@ -62,8 +65,17 @@ static void refresh_cache(struct cache *cache, const char *key) } cache->serial = serial; __system_property_read(cache->pinfo, 0, buf); switch(buf[0]) { case 't': case 'T': cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE; break; case 'f': case 'F': cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE; break; default: cache->c = buf[0]; } } static int __android_log_level(const char *tag, int default_prio) { Loading Loading @@ -147,6 +159,7 @@ static int __android_log_level(const char *tag, int default_prio) case 'F': /* Not officially supported */ case 'A': case 'S': case BOOLEAN_FALSE: /* Not officially supported */ break; default: /* clear '.' after log.tag */ Loading Loading @@ -180,6 +193,7 @@ static int __android_log_level(const char *tag, int default_prio) case 'E': return ANDROID_LOG_ERROR; case 'F': /* FALLTHRU */ /* Not officially supported */ case 'A': return ANDROID_LOG_FATAL; case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */ case 'S': return -1; /* ANDROID_LOG_SUPPRESS */ } return default_prio; Loading Loading @@ -226,3 +240,36 @@ clockid_t android_log_clockid() return (tolower(c) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME; } /* * security state generally remains constant, since a change is * rare, we can accept a trylock failure gracefully. */ static pthread_mutex_t lock_security = PTHREAD_MUTEX_INITIALIZER; int __android_log_security() { static struct cache r_do_cache = { NULL, -1, BOOLEAN_FALSE }; static struct cache p_security_cache = { NULL, -1, BOOLEAN_FALSE }; int retval; if (pthread_mutex_trylock(&lock_security)) { /* We are willing to accept some race in this context */ retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c && (p_security_cache.c == BOOLEAN_TRUE); } else { static uint32_t serial; uint32_t current_serial = __system_property_area_serial(); if (current_serial != serial) { refresh_cache(&r_do_cache, "ro.device_owner"); refresh_cache(&p_security_cache, "persist.logd.security"); serial = current_serial; } retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c && (p_security_cache.c == BOOLEAN_TRUE); pthread_mutex_unlock(&lock_security); } return retval; } liblog/tests/liblog_test.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,43 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) { android_logger_list_close(logger_list); } TEST(liblog, __security) { static const char persist_key[] = "persist.logd.security"; static const char readonly_key[] = "ro.device_owner"; static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_"; char persist[PROP_VALUE_MAX]; char readonly[PROP_VALUE_MAX]; property_get(persist_key, persist, ""); property_get(readonly_key, readonly, nothing_val); if (!strcmp(readonly, nothing_val)) { EXPECT_FALSE(__android_log_security()); fprintf(stderr, "Warning, setting ro.device_owner to a domain\n"); property_set(readonly_key, "com.google.android.SecOps.DeviceOwner"); } else if (!strcasecmp(readonly, "false") || !readonly[0]) { EXPECT_FALSE(__android_log_security()); return; } if (!strcasecmp(persist, "true")) { EXPECT_TRUE(__android_log_security()); } else { EXPECT_FALSE(__android_log_security()); } property_set(persist_key, "TRUE"); EXPECT_TRUE(__android_log_security()); property_set(persist_key, "FALSE"); EXPECT_FALSE(__android_log_security()); property_set(persist_key, "true"); EXPECT_TRUE(__android_log_security()); property_set(persist_key, "false"); EXPECT_FALSE(__android_log_security()); property_set(persist_key, ""); EXPECT_FALSE(__android_log_security()); property_set(persist_key, persist); } static unsigned signaled; log_time signal_time; Loading Loading
include/log/log.h +2 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,8 @@ typedef enum log_id { */ int __android_log_is_loggable(int prio, const char *tag, int default_prio); int __android_log_security(); /* Device Owner is present */ int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data, uint32_t dataLen); Loading
liblog/log_is_loggable.c +48 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ struct cache { char c; }; #define BOOLEAN_TRUE 0xFF #define BOOLEAN_FALSE 0xFE static void refresh_cache(struct cache *cache, const char *key) { uint32_t serial; Loading @@ -62,8 +65,17 @@ static void refresh_cache(struct cache *cache, const char *key) } cache->serial = serial; __system_property_read(cache->pinfo, 0, buf); switch(buf[0]) { case 't': case 'T': cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE; break; case 'f': case 'F': cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE; break; default: cache->c = buf[0]; } } static int __android_log_level(const char *tag, int default_prio) { Loading Loading @@ -147,6 +159,7 @@ static int __android_log_level(const char *tag, int default_prio) case 'F': /* Not officially supported */ case 'A': case 'S': case BOOLEAN_FALSE: /* Not officially supported */ break; default: /* clear '.' after log.tag */ Loading Loading @@ -180,6 +193,7 @@ static int __android_log_level(const char *tag, int default_prio) case 'E': return ANDROID_LOG_ERROR; case 'F': /* FALLTHRU */ /* Not officially supported */ case 'A': return ANDROID_LOG_FATAL; case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */ case 'S': return -1; /* ANDROID_LOG_SUPPRESS */ } return default_prio; Loading Loading @@ -226,3 +240,36 @@ clockid_t android_log_clockid() return (tolower(c) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME; } /* * security state generally remains constant, since a change is * rare, we can accept a trylock failure gracefully. */ static pthread_mutex_t lock_security = PTHREAD_MUTEX_INITIALIZER; int __android_log_security() { static struct cache r_do_cache = { NULL, -1, BOOLEAN_FALSE }; static struct cache p_security_cache = { NULL, -1, BOOLEAN_FALSE }; int retval; if (pthread_mutex_trylock(&lock_security)) { /* We are willing to accept some race in this context */ retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c && (p_security_cache.c == BOOLEAN_TRUE); } else { static uint32_t serial; uint32_t current_serial = __system_property_area_serial(); if (current_serial != serial) { refresh_cache(&r_do_cache, "ro.device_owner"); refresh_cache(&p_security_cache, "persist.logd.security"); serial = current_serial; } retval = (r_do_cache.c != BOOLEAN_FALSE) && r_do_cache.c && (p_security_cache.c == BOOLEAN_TRUE); pthread_mutex_unlock(&lock_security); } return retval; }
liblog/tests/liblog_test.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,43 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) { android_logger_list_close(logger_list); } TEST(liblog, __security) { static const char persist_key[] = "persist.logd.security"; static const char readonly_key[] = "ro.device_owner"; static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_"; char persist[PROP_VALUE_MAX]; char readonly[PROP_VALUE_MAX]; property_get(persist_key, persist, ""); property_get(readonly_key, readonly, nothing_val); if (!strcmp(readonly, nothing_val)) { EXPECT_FALSE(__android_log_security()); fprintf(stderr, "Warning, setting ro.device_owner to a domain\n"); property_set(readonly_key, "com.google.android.SecOps.DeviceOwner"); } else if (!strcasecmp(readonly, "false") || !readonly[0]) { EXPECT_FALSE(__android_log_security()); return; } if (!strcasecmp(persist, "true")) { EXPECT_TRUE(__android_log_security()); } else { EXPECT_FALSE(__android_log_security()); } property_set(persist_key, "TRUE"); EXPECT_TRUE(__android_log_security()); property_set(persist_key, "FALSE"); EXPECT_FALSE(__android_log_security()); property_set(persist_key, "true"); EXPECT_TRUE(__android_log_security()); property_set(persist_key, "false"); EXPECT_FALSE(__android_log_security()); property_set(persist_key, ""); EXPECT_FALSE(__android_log_security()); property_set(persist_key, persist); } static unsigned signaled; log_time signal_time; Loading