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

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

Merge "liblog: gate write on log id available"

parents d8c88fc5 c33103c4
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -105,12 +105,6 @@ static int logdAvailable(log_id_t logId)
    if (logId > LOG_ID_SECURITY) {
        return -EINVAL;
    }
    if (logId == LOG_ID_SECURITY) {
        uid_t uid = __android_log_uid();
        if ((uid != AID_LOG) && (uid != AID_ROOT) && (uid != AID_SYSTEM)) {
            return -EPERM;
        }
    }
    if (logdLoggerWrite.context.sock < 0) {
        if (access("/dev/socket/logdw", W_OK) == 0) {
            return 0;
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ union android_log_context {
struct android_log_transport_write {
  struct listnode node;
  const char *name;
  unsigned logMask; /* cache of available success */
  union android_log_context context; /* Initialized by static allocation */

  int (*available)(log_id_t logId);
+5 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <cutils/list.h>
#include <log/log.h>
#include <log/logger.h>
#include <private/android_filesystem_config.h>

#include "config_read.h"
#include "log_portability.h"
@@ -91,6 +92,10 @@ static int init_transport_context(struct android_log_logger_list *logger_list)
        logger_for_each(logger, logger_list) {
            log_id_t logId = logger->logId;

            if ((logId == LOG_ID_SECURITY) &&
                    (__android_log_uid() != AID_SYSTEM)) {
                continue;
            }
            if (transport->read &&
                    (!transport->available ||
                        (transport->available(logId) >= 0))) {
+94 −55
Original line number Diff line number Diff line
@@ -49,22 +49,87 @@ static enum {
    kLogUninitialized, kLogNotAvailable, kLogAvailable
} g_log_status = kLogUninitialized;

static int check_log_uid_permissions()
{
#if defined(__BIONIC__)
    uid_t uid = __android_log_uid();

    /* Matches clientHasLogCredentials() in logd */
    if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
        uid = geteuid();
        if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
            gid_t gid = getgid();
            if ((gid != AID_SYSTEM) &&
                    (gid != AID_ROOT) &&
                    (gid != AID_LOG)) {
                gid = getegid();
                if ((gid != AID_SYSTEM) &&
                        (gid != AID_ROOT) &&
                        (gid != AID_LOG)) {
                    int num_groups;
                    gid_t *groups;

                    num_groups = getgroups(0, NULL);
                    if (num_groups <= 0) {
                        return -EPERM;
                    }
                    groups = calloc(num_groups, sizeof(gid_t));
                    if (!groups) {
                        return -ENOMEM;
                    }
                    num_groups = getgroups(num_groups, groups);
                    while (num_groups > 0) {
                        if (groups[num_groups - 1] == AID_LOG) {
                            break;
                        }
                        --num_groups;
                    }
                    free(groups);
                    if (num_groups <= 0) {
                        return -EPERM;
                    }
                }
            }
        }
    }
#endif
    return 0;
}

static void __android_log_cache_available(
        struct android_log_transport_write *node)
{
    size_t i;

    if (node->logMask) {
        return;
    }

    for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
        if (node->write &&
                (i != LOG_ID_KERNEL) &&
                ((i != LOG_ID_SECURITY) ||
                    (check_log_uid_permissions() == 0)) &&
                (!node->available || ((*node->available)(i) >= 0))) {
            node->logMask |= 1 << i;
        }
    }
}

LIBLOG_ABI_PUBLIC int __android_log_dev_available()
{
    struct android_log_transport_write *node;
    size_t i;

    if (list_empty(&__android_log_transport_write)) {
        return kLogUninitialized;
    }
    for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {

    write_transport_for_each(node, &__android_log_transport_write) {
            if (node->write &&
                    (!node->available || ((*node->available)(i) >= 0))) {
        __android_log_cache_available(node);
        if (node->logMask) {
            return kLogAvailable;
        }
    }
    }
    return kLogNotAvailable;
}

@@ -77,6 +142,11 @@ static int __write_to_log_initialize()

    __android_log_config_write();
    write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
        __android_log_cache_available(transport);
        if (!transport->logMask) {
            list_remove(&transport->node);
            continue;
        }
        if (!transport->open || ((*transport->open)() < 0)) {
            if (transport->close) {
                (*transport->close)();
@@ -87,6 +157,11 @@ static int __write_to_log_initialize()
        ++ret;
    }
    write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
        __android_log_cache_available(transport);
        if (!transport->logMask) {
            list_remove(&transport->node);
            continue;
        }
        if (!transport->open || ((*transport->open)() < 0)) {
            if (transport->close) {
                (*transport->close)();
@@ -127,50 +202,13 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)

#if defined(__BIONIC__)
    if (log_id == LOG_ID_SECURITY) {
        uid_t uid;

        if (vec[0].iov_len < 4) {
            return -EINVAL;
        }

        uid = __android_log_uid();
        /* Matches clientHasLogCredentials() in logd */
        if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
            uid = geteuid();
            if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
                gid_t gid = getgid();
                if ((gid != AID_SYSTEM) &&
                        (gid != AID_ROOT) &&
                        (gid != AID_LOG)) {
                    gid = getegid();
                    if ((gid != AID_SYSTEM) &&
                            (gid != AID_ROOT) &&
                            (gid != AID_LOG)) {
                        int num_groups;
                        gid_t *groups;

                        num_groups = getgroups(0, NULL);
                        if (num_groups <= 0) {
                            return -EPERM;
                        }
                        groups = calloc(num_groups, sizeof(gid_t));
                        if (!groups) {
                            return -ENOMEM;
                        }
                        num_groups = getgroups(num_groups, groups);
                        while (num_groups > 0) {
                            if (groups[num_groups - 1] == AID_LOG) {
                                break;
                            }
                            --num_groups;
                        }
                        free(groups);
                        if (num_groups <= 0) {
                            return -EPERM;
                        }
                    }
                }
            }
        ret = check_log_uid_permissions();
        if (ret < 0) {
            return ret;
        }
        if (!__android_log_security()) {
            /* If only we could reset downstream logd counter */
@@ -262,8 +300,9 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
#endif

    ret = 0;
    i = 1 << log_id;
    write_transport_for_each(node, &__android_log_transport_write) {
        if (node->write) {
        if (node->logMask & i) {
            ssize_t retval;
            retval = (*node->write)(log_id, &ts, vec, nr);
            if (ret >= 0) {
@@ -273,7 +312,7 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
    }

    write_transport_for_each(node, &__android_log_persist_write) {
        if (node->write) {
        if (node->logMask & i) {
            (void)(*node->write)(log_id, &ts, vec, nr);
        }
    }