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 <endian.h>
     18 #include <errno.h>
     19 #include <fcntl.h>
     20 #include <inttypes.h>
     21 #include <poll.h>
     22 #include <stdarg.h>
     23 #include <stdatomic.h>
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include <sys/stat.h>
     28 #include <sys/types.h>
     29 #include <sys/socket.h>
     30 #include <sys/un.h>
     31 #include <time.h>
     32 #include <unistd.h>
     33 
     34 #include <cutils/sockets.h>
     35 #include <log/logd.h>
     36 #include <log/logger.h>
     37 #include <log/log_read.h>
     38 #include <private/android_filesystem_config.h>
     39 #include <private/android_logger.h>
     40 
     41 #include "config_read.h"
     42 #include "log_portability.h"
     43 #include "logger.h"
     44 
     45 /* branchless on many architectures. */
     46 #define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
     47 
     48 static int logdAvailable(log_id_t LogId);
     49 static int logdVersion(struct android_log_logger *logger,
     50                        struct android_log_transport_context *transp);
     51 static int logdRead(struct android_log_logger_list *logger_list,
     52                     struct android_log_transport_context *transp,
     53                     struct log_msg *log_msg);
     54 static int logdPoll(struct android_log_logger_list *logger_list,
     55                     struct android_log_transport_context *transp);
     56 static void logdClose(struct android_log_logger_list *logger_list,
     57                       struct android_log_transport_context *transp);
     58 static int logdClear(struct android_log_logger *logger,
     59                      struct android_log_transport_context *transp);
     60 static ssize_t logdSetSize(struct android_log_logger *logger,
     61                            struct android_log_transport_context *transp,
     62                            size_t size);
     63 static ssize_t logdGetSize(struct android_log_logger *logger,
     64                            struct android_log_transport_context *transp);
     65 static ssize_t logdGetReadableSize(struct android_log_logger *logger,
     66                                    struct android_log_transport_context *transp);
     67 static ssize_t logdGetPrune(struct android_log_logger_list *logger,
     68                             struct android_log_transport_context *transp,
     69                             char *buf, size_t len);
     70 static ssize_t logdSetPrune(struct android_log_logger_list *logger,
     71                             struct android_log_transport_context *transp,
     72                             char *buf, size_t len);
     73 static ssize_t logdGetStats(struct android_log_logger_list *logger,
     74                             struct android_log_transport_context *transp,
     75                             char *buf, size_t len);
     76 
     77 LIBLOG_HIDDEN struct android_log_transport_read logdLoggerRead = {
     78     .node = { &logdLoggerRead.node, &logdLoggerRead.node },
     79     .name = "logd",
     80     .available = logdAvailable,
     81     .version = logdVersion,
     82     .read = logdRead,
     83     .poll = logdPoll,
     84     .close = logdClose,
     85     .clear = logdClear,
     86     .getSize = logdGetSize,
     87     .setSize = logdSetSize,
     88     .getReadableSize = logdGetReadableSize,
     89     .getPrune = logdGetPrune,
     90     .setPrune = logdSetPrune,
     91     .getStats = logdGetStats,
     92 };
     93 
     94 static int logdAvailable(log_id_t logId)
     95 {
     96     if (logId > LOG_ID_KERNEL) {
     97         return -EINVAL;
     98     }
     99     if (logId == LOG_ID_SECURITY) {
    100         uid_t uid = __android_log_uid();
    101         if (uid != AID_SYSTEM) {
    102             return -EPERM;
    103         }
    104     }
    105     if (access("/dev/socket/logdw", W_OK) == 0) {
    106         return 0;
    107     }
    108     return -EBADF;
    109 }
    110 
    111 /* Private copy of ../libcutils/socket_local_client.c prevent library loops */
    112 
    113 #if defined(_WIN32)
    114 
    115 LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type)
    116 {
    117     errno = ENOSYS;
    118     return -ENOSYS;
    119 }
    120 
    121 #else /* !_WIN32 */
    122 
    123 #include <sys/socket.h>
    124 #include <sys/un.h>
    125 #include <sys/select.h>
    126 #include <sys/types.h>
    127 
    128 /* Private copy of ../libcutils/socket_local.h prevent library loops */
    129 #define FILESYSTEM_SOCKET_PREFIX "/tmp/"
    130 #define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"
    131 /* End of ../libcutils/socket_local.h */
    132 
    133 #define LISTEN_BACKLOG 4
    134 
    135 /* Documented in header file. */
    136 LIBLOG_WEAK int socket_make_sockaddr_un(const char *name, int namespaceId,
    137                                         struct sockaddr_un *p_addr,
    138                                         socklen_t *alen)
    139 {
    140     memset (p_addr, 0, sizeof (*p_addr));
    141     size_t namelen;
    142 
    143     switch (namespaceId) {
    144     case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
    145 #if defined(__linux__)
    146         namelen  = strlen(name);
    147 
    148         /* Test with length +1 for the *initial* '\0'. */
    149         if ((namelen + 1) > sizeof(p_addr->sun_path)) {
    150             goto error;
    151         }
    152 
    153         /*
    154          * Note: The path in this case is *not* supposed to be
    155          * '\0'-terminated. ("man 7 unix" for the gory details.)
    156          */
    157 
    158         p_addr->sun_path[0] = 0;
    159         memcpy(p_addr->sun_path + 1, name, namelen);
    160 #else
    161         /* this OS doesn't have the Linux abstract namespace */
    162 
    163         namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
    164         /* unix_path_max appears to be missing on linux */
    165         if (namelen > sizeof(*p_addr)
    166                 - offsetof(struct sockaddr_un, sun_path) - 1) {
    167             goto error;
    168         }
    169 
    170         strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
    171         strcat(p_addr->sun_path, name);
    172 #endif
    173         break;
    174 
    175     case ANDROID_SOCKET_NAMESPACE_RESERVED:
    176         namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
    177         /* unix_path_max appears to be missing on linux */
    178         if (namelen > sizeof(*p_addr)
    179                 - offsetof(struct sockaddr_un, sun_path) - 1) {
    180             goto error;
    181         }
    182 
    183         strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
    184         strcat(p_addr->sun_path, name);
    185         break;
    186 
    187     case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
    188         namelen = strlen(name);
    189         /* unix_path_max appears to be missing on linux */
    190         if (namelen > sizeof(*p_addr)
    191                 - offsetof(struct sockaddr_un, sun_path) - 1) {
    192             goto error;
    193         }
    194 
    195         strcpy(p_addr->sun_path, name);
    196         break;
    197 
    198     default:
    199         /* invalid namespace id */
    200         return -1;
    201     }
    202 
    203     p_addr->sun_family = AF_LOCAL;
    204     *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
    205     return 0;
    206 error:
    207     return -1;
    208 }
    209 
    210 /**
    211  * connect to peer named "name" on fd
    212  * returns same fd or -1 on error.
    213  * fd is not closed on error. that's your job.
    214  *
    215  * Used by AndroidSocketImpl
    216  */
    217 LIBLOG_WEAK int socket_local_client_connect(int fd, const char *name,
    218                                             int namespaceId, int type __unused)
    219 {
    220     struct sockaddr_un addr;
    221     socklen_t alen;
    222     int err;
    223 
    224     err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
    225 
    226     if (err < 0) {
    227         goto error;
    228     }
    229 
    230     if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {
    231         goto error;
    232     }
    233 
    234     return fd;
    235 
    236 error:
    237     return -1;
    238 }
    239 
    240 /**
    241  * connect to peer named "name"
    242  * returns fd or -1 on error
    243  */
    244 LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type)
    245 {
    246     int s;
    247 
    248     s = socket(AF_LOCAL, type, 0);
    249     if(s < 0) return -1;
    250 
    251     if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {
    252         close(s);
    253         return -1;
    254     }
    255 
    256     return s;
    257 }
    258 
    259 #endif /* !_WIN32 */
    260 /* End of ../libcutils/socket_local_client.c */
    261 
    262 /* worker for sending the command to the logger */
    263 static ssize_t send_log_msg(struct android_log_logger *logger,
    264                             const char *msg, char *buf, size_t buf_size)
    265 {
    266     ssize_t ret;
    267     size_t len;
    268     char *cp;
    269     int errno_save = 0;
    270     int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
    271                                    SOCK_STREAM);
    272     if (sock < 0) {
    273         return sock;
    274     }
    275 
    276     if (msg) {
    277         snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned) -1);
    278     }
    279 
    280     len = strlen(buf) + 1;
    281     ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
    282     if (ret <= 0) {
    283         goto done;
    284     }
    285 
    286     len = buf_size;
    287     cp = buf;
    288     while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
    289         struct pollfd p;
    290 
    291         if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
    292             break;
    293         }
    294 
    295         len -= ret;
    296         cp += ret;
    297 
    298         memset(&p, 0, sizeof(p));
    299         p.fd = sock;
    300         p.events = POLLIN;
    301 
    302         /* Give other side 20ms to refill pipe */
    303         ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
    304 
    305         if (ret <= 0) {
    306             break;
    307         }
    308 
    309         if (!(p.revents & POLLIN)) {
    310             ret = 0;
    311             break;
    312         }
    313     }
    314 
    315     if (ret >= 0) {
    316         ret += buf_size - len;
    317     }
    318 
    319 done:
    320     if ((ret == -1) && errno) {
    321         errno_save = errno;
    322     }
    323     close(sock);
    324     if (errno_save) {
    325         errno = errno_save;
    326     }
    327     return ret;
    328 }
    329 
    330 static int check_log_success(char *buf, ssize_t ret)
    331 {
    332     if (ret < 0) {
    333         return ret;
    334     }
    335 
    336     if (strncmp(buf, "success", 7)) {
    337         errno = EINVAL;
    338         return -1;
    339     }
    340 
    341     return 0;
    342 }
    343 
    344 static int logdClear(struct android_log_logger *logger,
    345                      struct android_log_transport_context *transp __unused)
    346 {
    347     char buf[512];
    348 
    349     return check_log_success(buf,
    350         send_log_msg(logger, "clear %d", buf, sizeof(buf)));
    351 }
    352 
    353 /* returns the total size of the log's ring buffer */
    354 static ssize_t logdGetSize(struct android_log_logger *logger,
    355                            struct android_log_transport_context *transp __unused)
    356 {
    357     char buf[512];
    358 
    359     ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
    360     if (ret < 0) {
    361         return ret;
    362     }
    363 
    364     if ((buf[0] < '0') || ('9' < buf[0])) {
    365         return -1;
    366     }
    367 
    368     return atol(buf);
    369 }
    370 
    371 static ssize_t logdSetSize(
    372         struct android_log_logger *logger,
    373         struct android_log_transport_context *transp __unused,
    374         size_t size)
    375 {
    376     char buf[512];
    377 
    378     snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
    379 
    380     return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
    381 }
    382 
    383 /*
    384  * returns the readable size of the log's ring buffer (that is, amount of the
    385  * log consumed)
    386  */
    387 static ssize_t logdGetReadableSize(
    388        struct android_log_logger *logger,
    389        struct android_log_transport_context *transp __unused)
    390 {
    391     char buf[512];
    392 
    393     ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
    394     if (ret < 0) {
    395         return ret;
    396     }
    397 
    398     if ((buf[0] < '0') || ('9' < buf[0])) {
    399         return -1;
    400     }
    401 
    402     return atol(buf);
    403 }
    404 
    405 /*
    406  * returns the logger version
    407  */
    408 static int logdVersion(
    409         struct android_log_logger *logger __unused,
    410         struct android_log_transport_context *transp __unused)
    411 {
    412     uid_t uid = __android_log_uid();
    413     return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
    414 }
    415 
    416 /*
    417  * returns statistics
    418  */
    419 static ssize_t logdGetStats(struct android_log_logger_list *logger_list,
    420                             struct android_log_transport_context *transp __unused,
    421                             char *buf, size_t len)
    422 {
    423     struct android_log_logger *logger;
    424     char *cp = buf;
    425     size_t remaining = len;
    426     size_t n;
    427 
    428     n = snprintf(cp, remaining, "getStatistics");
    429     n = min(n, remaining);
    430     remaining -= n;
    431     cp += n;
    432 
    433     logger_for_each(logger, logger_list) {
    434         n = snprintf(cp, remaining, " %d", logger->logId);
    435         n = min(n, remaining);
    436         remaining -= n;
    437         cp += n;
    438     }
    439 
    440     if (logger_list->pid) {
    441         snprintf(cp, remaining, " pid=%u", logger_list->pid);
    442     }
    443 
    444     return send_log_msg(NULL, NULL, buf, len);
    445 }
    446 
    447 static ssize_t logdGetPrune(
    448         struct android_log_logger_list *logger_list __unused,
    449         struct android_log_transport_context *transp __unused,
    450         char *buf, size_t len)
    451 {
    452     return send_log_msg(NULL, "getPruneList", buf, len);
    453 }
    454 
    455 static ssize_t logdSetPrune(
    456         struct android_log_logger_list *logger_list __unused,
    457         struct android_log_transport_context *transp __unused,
    458         char *buf, size_t len)
    459 {
    460     const char cmd[] = "setPruneList ";
    461     const size_t cmdlen = sizeof(cmd) - 1;
    462 
    463     if (strlen(buf) > (len - cmdlen)) {
    464         return -ENOMEM; /* KISS */
    465     }
    466     memmove(buf + cmdlen, buf, len - cmdlen);
    467     buf[len - 1] = '\0';
    468     memcpy(buf, cmd, cmdlen);
    469 
    470     return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
    471 }
    472 
    473 
    474 static void caught_signal(int signum __unused)
    475 {
    476 }
    477 
    478 static int logdOpen(struct android_log_logger_list *logger_list,
    479                     struct android_log_transport_context *transp)
    480 {
    481     struct android_log_logger *logger;
    482     struct sigaction ignore;
    483     struct sigaction old_sigaction;
    484     unsigned int old_alarm = 0;
    485     char buffer[256], *cp, c;
    486     int e, ret, remaining;
    487 
    488     int sock = transp->context.sock;
    489     if (sock > 0) {
    490         return sock;
    491     }
    492 
    493     if (!logger_list) {
    494         return -EINVAL;
    495     }
    496 
    497     sock = socket_local_client("logdr",
    498                                ANDROID_SOCKET_NAMESPACE_RESERVED,
    499                                SOCK_SEQPACKET);
    500     if (sock == 0) {
    501         /* Guarantee not file descriptor zero */
    502         int newsock = socket_local_client("logdr",
    503                                    ANDROID_SOCKET_NAMESPACE_RESERVED,
    504                                    SOCK_SEQPACKET);
    505         close(sock);
    506         sock = newsock;
    507     }
    508     if (sock <= 0) {
    509         if ((sock == -1) && errno) {
    510             return -errno;
    511         }
    512         return sock;
    513     }
    514 
    515     strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ?
    516             "dumpAndClose" : "stream");
    517     cp = buffer + strlen(buffer);
    518 
    519     strcpy(cp, " lids");
    520     cp += 5;
    521     c = '=';
    522     remaining = sizeof(buffer) - (cp - buffer);
    523     logger_for_each(logger, logger_list) {
    524         ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
    525         ret = min(ret, remaining);
    526         remaining -= ret;
    527         cp += ret;
    528         c = ',';
    529     }
    530 
    531     if (logger_list->tail) {
    532         ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
    533         ret = min(ret, remaining);
    534         remaining -= ret;
    535         cp += ret;
    536     }
    537 
    538     if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
    539         if (logger_list->mode & ANDROID_LOG_WRAP) {
    540             // ToDo: alternate API to allow timeout to be adjusted.
    541             ret = snprintf(cp, remaining, " timeout=%u",
    542                            ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
    543             ret = min(ret, remaining);
    544             remaining -= ret;
    545             cp += ret;
    546         }
    547         ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32,
    548                        logger_list->start.tv_sec,
    549                        logger_list->start.tv_nsec);
    550         ret = min(ret, remaining);
    551         remaining -= ret;
    552         cp += ret;
    553     }
    554 
    555     if (logger_list->pid) {
    556         ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
    557         ret = min(ret, remaining);
    558         cp += ret;
    559     }
    560 
    561     if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
    562         /* Deal with an unresponsive logd */
    563         memset(&ignore, 0, sizeof(ignore));
    564         ignore.sa_handler = caught_signal;
    565         sigemptyset(&ignore.sa_mask);
    566         /* particularily useful if tombstone is reporting for logd */
    567         sigaction(SIGALRM, &ignore, &old_sigaction);
    568         old_alarm = alarm(30);
    569     }
    570     ret = write(sock, buffer, cp - buffer);
    571     e = errno;
    572     if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
    573         if (e == EINTR) {
    574             e = ETIMEDOUT;
    575         }
    576         alarm(old_alarm);
    577         sigaction(SIGALRM, &old_sigaction, NULL);
    578     }
    579 
    580     if (ret <= 0) {
    581         close(sock);
    582         if ((ret == -1) && e) {
    583             return -e;
    584         }
    585         if (ret == 0) {
    586             return -EIO;
    587         }
    588         return ret;
    589     }
    590 
    591     return transp->context.sock = sock;
    592 }
    593 
    594 /* Read from the selected logs */
    595 static int logdRead(struct android_log_logger_list *logger_list,
    596                     struct android_log_transport_context *transp,
    597                     struct log_msg *log_msg)
    598 {
    599     int ret, e;
    600     struct sigaction ignore;
    601     struct sigaction old_sigaction;
    602     unsigned int old_alarm = 0;
    603 
    604     ret = logdOpen(logger_list, transp);
    605     if (ret < 0) {
    606         return ret;
    607     }
    608 
    609     memset(log_msg, 0, sizeof(*log_msg));
    610 
    611     if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
    612         memset(&ignore, 0, sizeof(ignore));
    613         ignore.sa_handler = caught_signal;
    614         sigemptyset(&ignore.sa_mask);
    615         /* particularily useful if tombstone is reporting for logd */
    616         sigaction(SIGALRM, &ignore, &old_sigaction);
    617         old_alarm = alarm(30);
    618     }
    619 
    620     /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
    621     ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
    622     e = errno;
    623 
    624     if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
    625         if ((ret == 0) || (e == EINTR)) {
    626             e = EAGAIN;
    627             ret = -1;
    628         }
    629         alarm(old_alarm);
    630         sigaction(SIGALRM, &old_sigaction, NULL);
    631     }
    632 
    633     if ((ret == -1) && e) {
    634         return -e;
    635     }
    636     return ret;
    637 }
    638 
    639 static int logdPoll(struct android_log_logger_list *logger_list,
    640                     struct android_log_transport_context *transp)
    641 {
    642     struct pollfd p;
    643 
    644     int ret = logdOpen(logger_list, transp);
    645     if (ret < 0) {
    646         return ret;
    647     }
    648 
    649     memset(&p, 0, sizeof(p));
    650     p.fd = ret;
    651     p.events = POLLIN;
    652     ret = poll(&p, 1, 20);
    653     if ((ret > 0) && !(p.revents & POLLIN)) {
    654         ret = 0;
    655     }
    656     if ((ret == -1) && errno) {
    657         return -errno;
    658     }
    659     return ret;
    660 }
    661 
    662 /* Close all the logs */
    663 static void logdClose(struct android_log_logger_list *logger_list __unused,
    664                       struct android_log_transport_context *transp)
    665 {
    666     if (transp->context.sock > 0) {
    667         close (transp->context.sock);
    668         transp->context.sock = -1;
    669     }
    670 }
    671