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

Commit 86052a5d authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

Merge "logd: liblog: logcat: Add LOG_ID_SECURITY"

parents 6945e360 083b037c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -604,7 +604,8 @@ typedef enum log_id {
    LOG_ID_EVENTS = 2,
    LOG_ID_SYSTEM = 3,
    LOG_ID_CRASH = 4,
    LOG_ID_KERNEL = 5,
    LOG_ID_SECURITY = 5,
    LOG_ID_KERNEL = 6, /* place last, third-parties can not use it */
#endif

    LOG_ID_MAX
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ int __android_log_btwrite(int32_t tag, char type, const void *payload,
    size_t len);
int __android_log_bswrite(int32_t tag, const char *payload);

int __android_log_security_bwrite(int32_t tag, const void *payload, size_t len);

#ifdef __cplusplus
}
#endif
+1 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ static const char *LOG_NAME[LOG_ID_MAX] = {
    [LOG_ID_EVENTS] = "events",
    [LOG_ID_SYSTEM] = "system",
    [LOG_ID_CRASH] = "crash",
    [LOG_ID_SECURITY] = "security",
    [LOG_ID_KERNEL] = "kernel",
};

+58 −3
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ static void unlock()
#endif  /* !defined(_WIN32) */

#if FAKE_LOG_DEVICE
static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };
static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1, -1 };
#else
static int logd_fd = -1;
static int pstore_fd = -1;
@@ -181,6 +181,7 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
    static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */
    static pid_t last_pid = (pid_t) -1;
    static atomic_int_fast32_t dropped;
    static atomic_int_fast32_t dropped_security;

    if (!nr) {
        return -EINVAL;
@@ -192,6 +193,23 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
    if (last_pid == (pid_t) -1) {
        last_pid = getpid();
    }
    if (log_id == LOG_ID_SECURITY) {
        if ((last_uid != AID_SYSTEM) && (last_uid != AID_ROOT)) {
            uid_t uid = geteuid();
            if ((uid != AID_SYSTEM) && (uid != AID_ROOT)) {
                gid_t gid = getgid();
                if ((gid != AID_SYSTEM) && (gid != AID_ROOT)) {
                    gid = getegid();
                    if ((gid != AID_SYSTEM) && (gid != AID_ROOT)) {
                        return -EPERM;
                    }
                }
            }
        }
        if (!__android_log_security()) {
            return -EPERM;
        }
    }
    /*
     *  struct {
     *      // what we provide to pstore
@@ -229,7 +247,26 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
    newVec[1].iov_len    = sizeof(header);

    if (logd_fd > 0) {
        int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
        int32_t snapshot = atomic_exchange_explicit(&dropped_security, 0,
                                                    memory_order_relaxed);
        if (snapshot) {
            android_log_event_int_t buffer;

            header.id = LOG_ID_SECURITY;
            buffer.header.tag = htole32(LIBLOG_LOG_TAG);
            buffer.payload.type = EVENT_TYPE_INT;
            buffer.payload.data = htole32(snapshot);

            newVec[2].iov_base = &buffer;
            newVec[2].iov_len  = sizeof(buffer);

            ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2));
            if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
                atomic_fetch_add_explicit(&dropped_security, snapshot,
                                          memory_order_relaxed);
            }
        }
        snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
        if (snapshot) {
            android_log_event_int_t buffer;

@@ -243,7 +280,8 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)

            ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2));
            if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
                atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);
                atomic_fetch_add_explicit(&dropped, snapshot,
                                          memory_order_relaxed);
            }
        }
    }
@@ -315,6 +353,10 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
        ret -= sizeof(header);
    } else if (ret == -EAGAIN) {
        atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
        if (log_id == LOG_ID_SECURITY) {
            atomic_fetch_add_explicit(&dropped_security, 1,
                                      memory_order_relaxed);
        }
    }
#endif

@@ -328,6 +370,7 @@ static const char *LOG_NAME[LOG_ID_MAX] = {
    [LOG_ID_EVENTS] = "events",
    [LOG_ID_SYSTEM] = "system",
    [LOG_ID_CRASH] = "crash",
    [LOG_ID_SECURITY] = "security",
    [LOG_ID_KERNEL] = "kernel",
};

@@ -483,6 +526,18 @@ int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
    return write_to_log(LOG_ID_EVENTS, vec, 2);
}

int __android_log_security_bwrite(int32_t tag, const void *payload, size_t len)
{
    struct iovec vec[2];

    vec[0].iov_base = &tag;
    vec[0].iov_len = sizeof(tag);
    vec[1].iov_base = (void*)payload;
    vec[1].iov_len = len;

    return write_to_log(LOG_ID_SECURITY, vec, 2);
}

/*
 * Like __android_log_bwrite, but takes the type as well.  Doesn't work
 * for the general case where we're generating lists of stuff, but very
+93 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <log/logger.h>
#include <log/log_read.h>
#include <log/logprint.h>
#include <private/android_logger.h>

// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
// non-syscall libs. Since we are only using this in the emergency of
@@ -201,6 +202,96 @@ TEST(liblog, __security) {
    property_set(persist_key, persist);
}

TEST(liblog, __security_buffer) {
    struct logger_list *logger_list;
    android_event_long_t buffer;

    static const char persist_key[] = "persist.logd.security";
    char persist[PROP_VALUE_MAX];
    bool set_persist = false;
    bool allow_security = false;

    if (__android_log_security()) {
        allow_security = true;
    } else {
        property_get(persist_key, persist, "");
        if (strcasecmp(persist, "true")) {
            property_set(persist_key, "TRUE");
            if (__android_log_security()) {
                allow_security = true;
                set_persist = true;
            } else {
                property_set(persist_key, persist);
            }
        }
    }

    if (!allow_security) {
        fprintf(stderr, "WARNING: "
                "security buffer disabled, bypassing end-to-end test\n");

        log_time ts(CLOCK_MONOTONIC);

        buffer.type = EVENT_TYPE_LONG;
        buffer.data = *(static_cast<uint64_t *>((void *)&ts));

        // expect failure!
        ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));

        return;
    }

    pid_t pid = getpid();

    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
        LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
        1000, pid)));

    log_time ts(CLOCK_MONOTONIC);

    buffer.type = EVENT_TYPE_LONG;
    buffer.data = *(static_cast<uint64_t *>((void *)&ts));

    ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
    usleep(1000000);

    int count = 0;

    for (;;) {
        log_msg log_msg;
        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
            break;
        }

        ASSERT_EQ(log_msg.entry.pid, pid);

        if ((log_msg.entry.len != (4 + 1 + 8))
         || (log_msg.id() != LOG_ID_SECURITY)) {
            continue;
        }

        char *eventData = log_msg.msg();

        if (eventData[4] != EVENT_TYPE_LONG) {
            continue;
        }

        log_time tx(eventData + 4 + 1);
        if (ts == tx) {
            ++count;
        }
    }

    if (set_persist) {
        property_set(persist_key, persist);
    }

    android_logger_list_close(logger_list);

    EXPECT_EQ(1, count);

}

static unsigned signaled;
log_time signal_time;

@@ -651,7 +742,8 @@ TEST(liblog, android_logger_get_) {
        EXPECT_EQ(id, android_logger_get_id(logger));
        EXPECT_LT(0, android_logger_get_log_size(logger));
        /* crash buffer is allowed to be empty, that is actually healthy! */
        if (android_logger_get_log_readable_size(logger) || strcmp("crash", name)) {
        if (android_logger_get_log_readable_size(logger) ||
                (strcmp("crash", name) && strcmp("security", name))) {
            EXPECT_LT(0, android_logger_get_log_readable_size(logger));
        }
        EXPECT_LT(0, android_logger_get_log_version(logger));
Loading