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