Home | History | Annotate | Download | only in liblog
      1 /*
      2  * Copyright (C) 2007-2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <errno.h>
     18 #include <stdatomic.h>
     19 #include <stdlib.h>
     20 #include <string.h>
     21 #include <sys/time.h>
     22 
     23 #ifdef __BIONIC__
     24 #include <android/set_abort_message.h>
     25 #endif
     26 
     27 #include <log/event_tag_map.h>
     28 #include <log/logd.h>
     29 #include <log/logger.h>
     30 #include <log/log_read.h>
     31 #include <private/android_filesystem_config.h>
     32 #include <private/android_logger.h>
     33 
     34 #include "config_write.h"
     35 #include "log_portability.h"
     36 #include "logger.h"
     37 
     38 #define LOG_BUF_SIZE 1024
     39 
     40 static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
     41 static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
     42 
     43 /*
     44  * This is used by the C++ code to decide if it should write logs through
     45  * the C code.  Basically, if /dev/socket/logd is available, we're running in
     46  * the simulator rather than a desktop tool and want to use the device.
     47  */
     48 static enum {
     49     kLogUninitialized, kLogNotAvailable, kLogAvailable
     50 } g_log_status = kLogUninitialized;
     51 
     52 static int check_log_uid_permissions()
     53 {
     54 #if defined(__BIONIC__)
     55     uid_t uid = __android_log_uid();
     56 
     57     /* Matches clientHasLogCredentials() in logd */
     58     if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
     59         uid = geteuid();
     60         if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
     61             gid_t gid = getgid();
     62             if ((gid != AID_SYSTEM) &&
     63                     (gid != AID_ROOT) &&
     64                     (gid != AID_LOG)) {
     65                 gid = getegid();
     66                 if ((gid != AID_SYSTEM) &&
     67                         (gid != AID_ROOT) &&
     68                         (gid != AID_LOG)) {
     69                     int num_groups;
     70                     gid_t *groups;
     71 
     72                     num_groups = getgroups(0, NULL);
     73                     if (num_groups <= 0) {
     74                         return -EPERM;
     75                     }
     76                     groups = calloc(num_groups, sizeof(gid_t));
     77                     if (!groups) {
     78                         return -ENOMEM;
     79                     }
     80                     num_groups = getgroups(num_groups, groups);
     81                     while (num_groups > 0) {
     82                         if (groups[num_groups - 1] == AID_LOG) {
     83                             break;
     84                         }
     85                         --num_groups;
     86                     }
     87                     free(groups);
     88                     if (num_groups <= 0) {
     89                         return -EPERM;
     90                     }
     91                 }
     92             }
     93         }
     94     }
     95 #endif
     96     return 0;
     97 }
     98 
     99 static void __android_log_cache_available(
    100         struct android_log_transport_write *node)
    101 {
    102     size_t i;
    103 
    104     if (node->logMask) {
    105         return;
    106     }
    107 
    108     for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
    109         if (node->write &&
    110                 (i != LOG_ID_KERNEL) &&
    111                 ((i != LOG_ID_SECURITY) ||
    112                     (check_log_uid_permissions() == 0)) &&
    113                 (!node->available || ((*node->available)(i) >= 0))) {
    114             node->logMask |= 1 << i;
    115         }
    116     }
    117 }
    118 
    119 LIBLOG_ABI_PUBLIC int __android_log_dev_available()
    120 {
    121     struct android_log_transport_write *node;
    122 
    123     if (list_empty(&__android_log_transport_write)) {
    124         return kLogUninitialized;
    125     }
    126 
    127     write_transport_for_each(node, &__android_log_transport_write) {
    128         __android_log_cache_available(node);
    129         if (node->logMask) {
    130             return kLogAvailable;
    131         }
    132     }
    133     return kLogNotAvailable;
    134 }
    135 /*
    136  * Release any logger resources. A new log write will immediately re-acquire.
    137  */
    138 LIBLOG_ABI_PUBLIC void __android_log_close()
    139 {
    140     struct android_log_transport_write *transport;
    141 
    142     __android_log_lock();
    143 
    144     write_to_log = __write_to_log_init;
    145 
    146     /*
    147      * Threads that are actively writing at this point are not held back
    148      * by a lock and are at risk of dropping the messages with a return code
    149      * -EBADF. Prefer to return error code than add the overhead of a lock to
    150      * each log writing call to guarantee delivery. In addition, anyone
    151      * calling this is doing so to release the logging resources and shut down,
    152      * for them to do so with outstanding log requests in other threads is a
    153      * disengenuous use of this function.
    154      */
    155 
    156     write_transport_for_each(transport, &__android_log_persist_write) {
    157         if (transport->close) {
    158             (*transport->close)();
    159         }
    160     }
    161 
    162     write_transport_for_each(transport, &__android_log_transport_write) {
    163         if (transport->close) {
    164             (*transport->close)();
    165         }
    166     }
    167 
    168     __android_log_unlock();
    169 }
    170 
    171 /* log_init_lock assumed */
    172 static int __write_to_log_initialize()
    173 {
    174     struct android_log_transport_write *transport;
    175     struct listnode *n;
    176     int i = 0, ret = 0;
    177 
    178     __android_log_config_write();
    179     write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
    180         __android_log_cache_available(transport);
    181         if (!transport->logMask) {
    182             list_remove(&transport->node);
    183             continue;
    184         }
    185         if (!transport->open || ((*transport->open)() < 0)) {
    186             if (transport->close) {
    187                 (*transport->close)();
    188             }
    189             list_remove(&transport->node);
    190             continue;
    191         }
    192         ++ret;
    193     }
    194     write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
    195         __android_log_cache_available(transport);
    196         if (!transport->logMask) {
    197             list_remove(&transport->node);
    198             continue;
    199         }
    200         if (!transport->open || ((*transport->open)() < 0)) {
    201             if (transport->close) {
    202                 (*transport->close)();
    203             }
    204             list_remove(&transport->node);
    205             continue;
    206         }
    207         ++i;
    208     }
    209     if (!ret && !i) {
    210         return -ENODEV;
    211     }
    212 
    213     return ret;
    214 }
    215 
    216 /*
    217  * Extract a 4-byte value from a byte stream. le32toh open coded
    218  */
    219 static inline uint32_t get4LE(const uint8_t* src)
    220 {
    221     return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
    222 }
    223 
    224 static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
    225 {
    226     struct android_log_transport_write *node;
    227     int ret;
    228     struct timespec ts;
    229     size_t len, i;
    230 
    231     for (len = i = 0; i < nr; ++i) {
    232         len += vec[i].iov_len;
    233     }
    234     if (!len) {
    235         return -EINVAL;
    236     }
    237 
    238 #if defined(__BIONIC__)
    239     if (log_id == LOG_ID_SECURITY) {
    240         if (vec[0].iov_len < 4) {
    241             return -EINVAL;
    242         }
    243 
    244         ret = check_log_uid_permissions();
    245         if (ret < 0) {
    246             return ret;
    247         }
    248         if (!__android_log_security()) {
    249             /* If only we could reset downstream logd counter */
    250             return -EPERM;
    251         }
    252     } else if (log_id == LOG_ID_EVENTS) {
    253         static atomic_uintptr_t map;
    254         const char *tag;
    255         EventTagMap *m, *f;
    256 
    257         if (vec[0].iov_len < 4) {
    258             return -EINVAL;
    259         }
    260 
    261         tag = NULL;
    262         f = NULL;
    263         m = (EventTagMap *)atomic_load(&map);
    264 
    265         if (!m) {
    266             ret = __android_log_trylock();
    267             m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */
    268             if (!m) {
    269                 m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
    270                 if (ret) { /* trylock failed, use local copy, mark for close */
    271                     f = m;
    272                 } else {
    273                     if (!m) { /* One chance to open map file */
    274                         m = (EventTagMap *)(uintptr_t)-1LL;
    275                     }
    276                     atomic_store(&map, (uintptr_t)m);
    277                 }
    278             }
    279             if (!ret) { /* trylock succeeded, unlock */
    280                 __android_log_unlock();
    281             }
    282         }
    283         if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
    284             tag = android_lookupEventTag(m, get4LE(vec[0].iov_base));
    285         }
    286         ret = __android_log_is_loggable(ANDROID_LOG_INFO,
    287                                         tag,
    288                                         ANDROID_LOG_VERBOSE);
    289         if (f) { /* local copy marked for close */
    290             android_closeEventTagMap(f);
    291         }
    292         if (!ret) {
    293             return -EPERM;
    294         }
    295     } else {
    296         /* Validate the incoming tag, tag content can not split across iovec */
    297         char prio = ANDROID_LOG_VERBOSE;
    298         const char *tag = vec[0].iov_base;
    299         size_t len = vec[0].iov_len;
    300         if (!tag) {
    301             len = 0;
    302         }
    303         if (len > 0) {
    304             prio = *tag;
    305             if (len > 1) {
    306                 --len;
    307                 ++tag;
    308             } else {
    309                 len = vec[1].iov_len;
    310                 tag = ((const char *)vec[1].iov_base);
    311                 if (!tag) {
    312                     len = 0;
    313                 }
    314             }
    315         }
    316         /* tag must be nul terminated */
    317         if (strnlen(tag, len) >= len) {
    318             tag = NULL;
    319         }
    320 
    321         if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
    322             return -EPERM;
    323         }
    324     }
    325 
    326     clock_gettime(android_log_clockid(), &ts);
    327 #else
    328     /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
    329     {
    330         struct timeval tv;
    331         gettimeofday(&tv, NULL);
    332         ts.tv_sec = tv.tv_sec;
    333         ts.tv_nsec = tv.tv_usec * 1000;
    334     }
    335 #endif
    336 
    337     ret = 0;
    338     i = 1 << log_id;
    339     write_transport_for_each(node, &__android_log_transport_write) {
    340         if (node->logMask & i) {
    341             ssize_t retval;
    342             retval = (*node->write)(log_id, &ts, vec, nr);
    343             if (ret >= 0) {
    344                 ret = retval;
    345             }
    346         }
    347     }
    348 
    349     write_transport_for_each(node, &__android_log_persist_write) {
    350         if (node->logMask & i) {
    351             (void)(*node->write)(log_id, &ts, vec, nr);
    352         }
    353     }
    354 
    355     return ret;
    356 }
    357 
    358 static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
    359 {
    360     __android_log_lock();
    361 
    362     if (write_to_log == __write_to_log_init) {
    363         int ret;
    364 
    365         ret = __write_to_log_initialize();
    366         if (ret < 0) {
    367             __android_log_unlock();
    368             if (!list_empty(&__android_log_persist_write)) {
    369                 __write_to_log_daemon(log_id, vec, nr);
    370             }
    371             return ret;
    372         }
    373 
    374         write_to_log = __write_to_log_daemon;
    375     }
    376 
    377     __android_log_unlock();
    378 
    379     return write_to_log(log_id, vec, nr);
    380 }
    381 
    382 LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,
    383                                           const char *msg)
    384 {
    385     return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
    386 }
    387 
    388 LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
    389                                               const char *tag, const char *msg)
    390 {
    391     struct iovec vec[3];
    392     char tmp_tag[32];
    393 
    394     if (!tag)
    395         tag = "";
    396 
    397     /* XXX: This needs to go! */
    398     if ((bufID != LOG_ID_RADIO) &&
    399          (!strcmp(tag, "HTC_RIL") ||
    400         !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
    401         !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
    402         !strcmp(tag, "AT") ||
    403         !strcmp(tag, "GSM") ||
    404         !strcmp(tag, "STK") ||
    405         !strcmp(tag, "CDMA") ||
    406         !strcmp(tag, "PHONE") ||
    407         !strcmp(tag, "SMS"))) {
    408             bufID = LOG_ID_RADIO;
    409             /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
    410             snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
    411             tag = tmp_tag;
    412     }
    413 
    414 #if __BIONIC__
    415     if (prio == ANDROID_LOG_FATAL) {
    416         android_set_abort_message(msg);
    417     }
    418 #endif
    419 
    420     vec[0].iov_base = (unsigned char *)&prio;
    421     vec[0].iov_len  = 1;
    422     vec[1].iov_base = (void *)tag;
    423     vec[1].iov_len  = strlen(tag) + 1;
    424     vec[2].iov_base = (void *)msg;
    425     vec[2].iov_len  = strlen(msg) + 1;
    426 
    427     return write_to_log(bufID, vec, 3);
    428 }
    429 
    430 LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag,
    431                                            const char *fmt, va_list ap)
    432 {
    433     char buf[LOG_BUF_SIZE];
    434 
    435     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
    436 
    437     return __android_log_write(prio, tag, buf);
    438 }
    439 
    440 LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag,
    441                                           const char *fmt, ...)
    442 {
    443     va_list ap;
    444     char buf[LOG_BUF_SIZE];
    445 
    446     va_start(ap, fmt);
    447     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
    448     va_end(ap);
    449 
    450     return __android_log_write(prio, tag, buf);
    451 }
    452 
    453 LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,
    454                                               const char *tag,
    455                                               const char *fmt, ...)
    456 {
    457     va_list ap;
    458     char buf[LOG_BUF_SIZE];
    459 
    460     va_start(ap, fmt);
    461     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
    462     va_end(ap);
    463 
    464     return __android_log_buf_write(bufID, prio, tag, buf);
    465 }
    466 
    467 LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag,
    468                                             const char *fmt, ...)
    469 {
    470     char buf[LOG_BUF_SIZE];
    471 
    472     if (fmt) {
    473         va_list ap;
    474         va_start(ap, fmt);
    475         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
    476         va_end(ap);
    477     } else {
    478         /* Msg not provided, log condition.  N.B. Do not use cond directly as
    479          * format string as it could contain spurious '%' syntax (e.g.
    480          * "%d" in "blocks%devs == 0").
    481          */
    482         if (cond)
    483             snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
    484         else
    485             strcpy(buf, "Unspecified assertion failed");
    486     }
    487 
    488     __android_log_write(ANDROID_LOG_FATAL, tag, buf);
    489     abort(); /* abort so we have a chance to debug the situation */
    490     /* NOTREACHED */
    491 }
    492 
    493 LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag,
    494                                            const void *payload, size_t len)
    495 {
    496     struct iovec vec[2];
    497 
    498     vec[0].iov_base = &tag;
    499     vec[0].iov_len = sizeof(tag);
    500     vec[1].iov_base = (void*)payload;
    501     vec[1].iov_len = len;
    502 
    503     return write_to_log(LOG_ID_EVENTS, vec, 2);
    504 }
    505 
    506 LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
    507                                                     const void *payload,
    508                                                     size_t len)
    509 {
    510     struct iovec vec[2];
    511 
    512     vec[0].iov_base = &tag;
    513     vec[0].iov_len = sizeof(tag);
    514     vec[1].iov_base = (void*)payload;
    515     vec[1].iov_len = len;
    516 
    517     return write_to_log(LOG_ID_SECURITY, vec, 2);
    518 }
    519 
    520 /*
    521  * Like __android_log_bwrite, but takes the type as well.  Doesn't work
    522  * for the general case where we're generating lists of stuff, but very
    523  * handy if we just want to dump an integer into the log.
    524  */
    525 LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,
    526                                             const void *payload, size_t len)
    527 {
    528     struct iovec vec[3];
    529 
    530     vec[0].iov_base = &tag;
    531     vec[0].iov_len = sizeof(tag);
    532     vec[1].iov_base = &type;
    533     vec[1].iov_len = sizeof(type);
    534     vec[2].iov_base = (void*)payload;
    535     vec[2].iov_len = len;
    536 
    537     return write_to_log(LOG_ID_EVENTS, vec, 3);
    538 }
    539 
    540 /*
    541  * Like __android_log_bwrite, but used for writing strings to the
    542  * event log.
    543  */
    544 LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload)
    545 {
    546     struct iovec vec[4];
    547     char type = EVENT_TYPE_STRING;
    548     uint32_t len = strlen(payload);
    549 
    550     vec[0].iov_base = &tag;
    551     vec[0].iov_len = sizeof(tag);
    552     vec[1].iov_base = &type;
    553     vec[1].iov_len = sizeof(type);
    554     vec[2].iov_base = &len;
    555     vec[2].iov_len = sizeof(len);
    556     vec[3].iov_base = (void*)payload;
    557     vec[3].iov_len = len;
    558 
    559     return write_to_log(LOG_ID_EVENTS, vec, 4);
    560 }
    561 
    562 /*
    563  * Like __android_log_security_bwrite, but used for writing strings to the
    564  * security log.
    565  */
    566 LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
    567                                                      const char *payload)
    568 {
    569     struct iovec vec[4];
    570     char type = EVENT_TYPE_STRING;
    571     uint32_t len = strlen(payload);
    572 
    573     vec[0].iov_base = &tag;
    574     vec[0].iov_len = sizeof(tag);
    575     vec[1].iov_base = &type;
    576     vec[1].iov_len = sizeof(type);
    577     vec[2].iov_base = &len;
    578     vec[2].iov_len = sizeof(len);
    579     vec[3].iov_base = (void*)payload;
    580     vec[3].iov_len = len;
    581 
    582     return write_to_log(LOG_ID_SECURITY, vec, 4);
    583 }
    584