Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffbd86ff authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

liblog: Add __android_log_security()

Return non-zero if ro.device_owner is set and not false
and persist.logd.security is true.

Bug: 26029733
Change-Id: Ie82ae11ae35e9c79017b6e873fefb39d79a1d4fe
parent 4ab13d02
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);

+48 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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)
{
@@ -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 */
@@ -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;
@@ -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;
}
+37 −0
Original line number Diff line number Diff line
@@ -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;