Home | History | Annotate | Download | only in liblog
      1 /*
      2  * Copyright (C) 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 <inttypes.h>
     19 #include <stdbool.h>
     20 #include <stdint.h>
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 
     25 #include <log/log_event_list.h>
     26 #include <private/android_logger.h>
     27 
     28 #include "log_portability.h"
     29 
     30 #define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
     31 
     32 typedef struct {
     33   uint32_t tag;
     34   unsigned pos; /* Read/write position into buffer */
     35   unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements   */
     36   unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1];  /* pos for list counter */
     37   unsigned list_nest_depth;
     38   unsigned len; /* Length or raw buffer. */
     39   bool overflow;
     40   bool list_stop; /* next call decrement list_nest_depth and issue a stop */
     41   enum {
     42     kAndroidLoggerRead = 1,
     43     kAndroidLoggerWrite = 2,
     44   } read_write_flag;
     45   uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
     46 } android_log_context_internal;
     47 
     48 LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
     49   size_t needed, i;
     50   android_log_context_internal* context;
     51 
     52   context = calloc(1, sizeof(android_log_context_internal));
     53   if (!context) {
     54     return NULL;
     55   }
     56   context->tag = tag;
     57   context->read_write_flag = kAndroidLoggerWrite;
     58   needed = sizeof(uint8_t) + sizeof(uint8_t);
     59   if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
     60     context->overflow = true;
     61   }
     62   /* Everything is a list */
     63   context->storage[context->pos + 0] = EVENT_TYPE_LIST;
     64   context->list[0] = context->pos + 1;
     65   context->pos += needed;
     66 
     67   return (android_log_context)context;
     68 }
     69 
     70 LIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(const char* msg,
     71                                                                 size_t len) {
     72   android_log_context_internal* context;
     73   size_t i;
     74 
     75   context = calloc(1, sizeof(android_log_context_internal));
     76   if (!context) {
     77     return NULL;
     78   }
     79   len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
     80   context->len = len;
     81   memcpy(context->storage, msg, len);
     82   context->read_write_flag = kAndroidLoggerRead;
     83 
     84   return (android_log_context)context;
     85 }
     86 
     87 LIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context* ctx) {
     88   android_log_context_internal* context;
     89 
     90   context = (android_log_context_internal*)*ctx;
     91   if (!context) {
     92     return -EBADF;
     93   }
     94   memset(context, 0, sizeof(*context));
     95   free(context);
     96   *ctx = NULL;
     97   return 0;
     98 }
     99 
    100 LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {
    101   size_t needed;
    102   android_log_context_internal* context;
    103 
    104   context = (android_log_context_internal*)ctx;
    105   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    106     return -EBADF;
    107   }
    108   if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
    109     context->overflow = true;
    110     return -EOVERFLOW;
    111   }
    112   needed = sizeof(uint8_t) + sizeof(uint8_t);
    113   if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
    114     context->overflow = true;
    115     return -EIO;
    116   }
    117   context->count[context->list_nest_depth]++;
    118   context->list_nest_depth++;
    119   if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
    120     context->overflow = true;
    121     return -EOVERFLOW;
    122   }
    123   if (context->overflow) {
    124     return -EIO;
    125   }
    126   context->storage[context->pos + 0] = EVENT_TYPE_LIST;
    127   context->storage[context->pos + 1] = 0;
    128   context->list[context->list_nest_depth] = context->pos + 1;
    129   context->count[context->list_nest_depth] = 0;
    130   context->pos += needed;
    131   return 0;
    132 }
    133 
    134 static inline void copy4LE(uint8_t* buf, uint32_t val) {
    135   buf[0] = val & 0xFF;
    136   buf[1] = (val >> 8) & 0xFF;
    137   buf[2] = (val >> 16) & 0xFF;
    138   buf[3] = (val >> 24) & 0xFF;
    139 }
    140 
    141 LIBLOG_ABI_PUBLIC int android_log_write_int32(android_log_context ctx,
    142                                               int32_t value) {
    143   size_t needed;
    144   android_log_context_internal* context;
    145 
    146   context = (android_log_context_internal*)ctx;
    147   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    148     return -EBADF;
    149   }
    150   if (context->overflow) {
    151     return -EIO;
    152   }
    153   needed = sizeof(uint8_t) + sizeof(value);
    154   if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
    155     context->overflow = true;
    156     return -EIO;
    157   }
    158   context->count[context->list_nest_depth]++;
    159   context->storage[context->pos + 0] = EVENT_TYPE_INT;
    160   copy4LE(&context->storage[context->pos + 1], value);
    161   context->pos += needed;
    162   return 0;
    163 }
    164 
    165 static inline void copy8LE(uint8_t* buf, uint64_t val) {
    166   buf[0] = val & 0xFF;
    167   buf[1] = (val >> 8) & 0xFF;
    168   buf[2] = (val >> 16) & 0xFF;
    169   buf[3] = (val >> 24) & 0xFF;
    170   buf[4] = (val >> 32) & 0xFF;
    171   buf[5] = (val >> 40) & 0xFF;
    172   buf[6] = (val >> 48) & 0xFF;
    173   buf[7] = (val >> 56) & 0xFF;
    174 }
    175 
    176 LIBLOG_ABI_PUBLIC int android_log_write_int64(android_log_context ctx,
    177                                               int64_t value) {
    178   size_t needed;
    179   android_log_context_internal* context;
    180 
    181   context = (android_log_context_internal*)ctx;
    182   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    183     return -EBADF;
    184   }
    185   if (context->overflow) {
    186     return -EIO;
    187   }
    188   needed = sizeof(uint8_t) + sizeof(value);
    189   if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
    190     context->overflow = true;
    191     return -EIO;
    192   }
    193   context->count[context->list_nest_depth]++;
    194   context->storage[context->pos + 0] = EVENT_TYPE_LONG;
    195   copy8LE(&context->storage[context->pos + 1], value);
    196   context->pos += needed;
    197   return 0;
    198 }
    199 
    200 LIBLOG_ABI_PUBLIC int android_log_write_string8_len(android_log_context ctx,
    201                                                     const char* value,
    202                                                     size_t maxlen) {
    203   size_t needed;
    204   ssize_t len;
    205   android_log_context_internal* context;
    206 
    207   context = (android_log_context_internal*)ctx;
    208   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    209     return -EBADF;
    210   }
    211   if (context->overflow) {
    212     return -EIO;
    213   }
    214   if (!value) {
    215     value = "";
    216   }
    217   len = strnlen(value, maxlen);
    218   needed = sizeof(uint8_t) + sizeof(int32_t) + len;
    219   if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
    220     /* Truncate string for delivery */
    221     len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
    222     if (len <= 0) {
    223       context->overflow = true;
    224       return -EIO;
    225     }
    226   }
    227   context->count[context->list_nest_depth]++;
    228   context->storage[context->pos + 0] = EVENT_TYPE_STRING;
    229   copy4LE(&context->storage[context->pos + 1], len);
    230   if (len) {
    231     memcpy(&context->storage[context->pos + 5], value, len);
    232   }
    233   context->pos += needed;
    234   return len;
    235 }
    236 
    237 LIBLOG_ABI_PUBLIC int android_log_write_string8(android_log_context ctx,
    238                                                 const char* value) {
    239   return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
    240 }
    241 
    242 LIBLOG_ABI_PUBLIC int android_log_write_float32(android_log_context ctx,
    243                                                 float value) {
    244   size_t needed;
    245   uint32_t ivalue;
    246   android_log_context_internal* context;
    247 
    248   context = (android_log_context_internal*)ctx;
    249   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    250     return -EBADF;
    251   }
    252   if (context->overflow) {
    253     return -EIO;
    254   }
    255   needed = sizeof(uint8_t) + sizeof(ivalue);
    256   if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
    257     context->overflow = true;
    258     return -EIO;
    259   }
    260   ivalue = *(uint32_t*)&value;
    261   context->count[context->list_nest_depth]++;
    262   context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
    263   copy4LE(&context->storage[context->pos + 1], ivalue);
    264   context->pos += needed;
    265   return 0;
    266 }
    267 
    268 LIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) {
    269   android_log_context_internal* context;
    270 
    271   context = (android_log_context_internal*)ctx;
    272   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    273     return -EBADF;
    274   }
    275   if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
    276     context->overflow = true;
    277     context->list_nest_depth--;
    278     return -EOVERFLOW;
    279   }
    280   if (!context->list_nest_depth) {
    281     context->overflow = true;
    282     return -EOVERFLOW;
    283   }
    284   if (context->list[context->list_nest_depth] <= 0) {
    285     context->list_nest_depth--;
    286     context->overflow = true;
    287     return -EOVERFLOW;
    288   }
    289   context->storage[context->list[context->list_nest_depth]] =
    290       context->count[context->list_nest_depth];
    291   context->list_nest_depth--;
    292   return 0;
    293 }
    294 
    295 /*
    296  * Logs the list of elements to the event log.
    297  */
    298 LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,
    299                                              log_id_t id) {
    300   android_log_context_internal* context;
    301   const char* msg;
    302   ssize_t len;
    303 
    304   if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (id != LOG_ID_STATS)) {
    305     return -EINVAL;
    306   }
    307 
    308   context = (android_log_context_internal*)ctx;
    309   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    310     return -EBADF;
    311   }
    312   if (context->list_nest_depth) {
    313     return -EIO;
    314   }
    315   /* NB: if there was overflow, then log is truncated. Nothing reported */
    316   context->storage[1] = context->count[0];
    317   len = context->len = context->pos;
    318   msg = (const char*)context->storage;
    319   /* it's not a list */
    320   if (context->count[0] <= 1) {
    321     len -= sizeof(uint8_t) + sizeof(uint8_t);
    322     if (len < 0) {
    323       len = 0;
    324     }
    325     msg += sizeof(uint8_t) + sizeof(uint8_t);
    326   }
    327   return (id == LOG_ID_EVENTS)
    328              ? __android_log_bwrite(context->tag, msg, len)
    329              : ((id == LOG_ID_STATS)
    330                     ? __android_log_stats_bwrite(context->tag, msg, len)
    331                     : __android_log_security_bwrite(context->tag, msg, len));
    332 }
    333 
    334 LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
    335                                                      const char** buffer) {
    336   android_log_context_internal* context;
    337   const char* msg;
    338   ssize_t len;
    339 
    340   context = (android_log_context_internal*)ctx;
    341   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    342     return -EBADF;
    343   }
    344   if (context->list_nest_depth) {
    345     return -EIO;
    346   }
    347   if (buffer == NULL) {
    348     return -EFAULT;
    349   }
    350   /* NB: if there was overflow, then log is truncated. Nothing reported */
    351   context->storage[1] = context->count[0];
    352   len = context->len = context->pos;
    353   msg = (const char*)context->storage;
    354   /* it's not a list */
    355   if (context->count[0] <= 1) {
    356     len -= sizeof(uint8_t) + sizeof(uint8_t);
    357     if (len < 0) {
    358       len = 0;
    359     }
    360     msg += sizeof(uint8_t) + sizeof(uint8_t);
    361   }
    362   *buffer = msg;
    363   return len;
    364 }
    365 
    366 /*
    367  * Extract a 4-byte value from a byte stream.
    368  */
    369 static inline uint32_t get4LE(const uint8_t* src) {
    370   return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
    371 }
    372 
    373 /*
    374  * Extract an 8-byte value from a byte stream.
    375  */
    376 static inline uint64_t get8LE(const uint8_t* src) {
    377   uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
    378   uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
    379   return ((uint64_t)high << 32) | (uint64_t)low;
    380 }
    381 
    382 /*
    383  * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
    384  * If there is nothing to process, the complete field is set to non-zero. If
    385  * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
    386  * this and continues to call this function, the behavior is undefined
    387  * (although it won't crash).
    388  */
    389 static android_log_list_element android_log_read_next_internal(
    390     android_log_context ctx, int peek) {
    391   android_log_list_element elem;
    392   unsigned pos;
    393   android_log_context_internal* context;
    394 
    395   context = (android_log_context_internal*)ctx;
    396 
    397   memset(&elem, 0, sizeof(elem));
    398 
    399   /* Nothing to parse from this context, so return complete. */
    400   if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
    401       (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
    402       (context->count[context->list_nest_depth] >=
    403        (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
    404     elem.type = EVENT_TYPE_UNKNOWN;
    405     if (context && (context->list_stop ||
    406                     ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
    407                      !context->count[context->list_nest_depth]))) {
    408       elem.type = EVENT_TYPE_LIST_STOP;
    409     }
    410     elem.complete = true;
    411     return elem;
    412   }
    413 
    414   /*
    415    * Use a different variable to update the position in case this
    416    * operation is a "peek".
    417    */
    418   pos = context->pos;
    419   if (context->list_stop) {
    420     elem.type = EVENT_TYPE_LIST_STOP;
    421     elem.complete = !context->count[0] &&
    422                     (!context->list_nest_depth ||
    423                      ((context->list_nest_depth == 1) && !context->count[1]));
    424     if (!peek) {
    425       /* Suck in superfluous stop */
    426       if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
    427         context->pos = pos + 1;
    428       }
    429       if (context->list_nest_depth) {
    430         --context->list_nest_depth;
    431         if (context->count[context->list_nest_depth]) {
    432           context->list_stop = false;
    433         }
    434       } else {
    435         context->list_stop = false;
    436       }
    437     }
    438     return elem;
    439   }
    440   if ((pos + 1) > context->len) {
    441     elem.type = EVENT_TYPE_UNKNOWN;
    442     elem.complete = true;
    443     return elem;
    444   }
    445 
    446   elem.type = context->storage[pos++];
    447   switch ((int)elem.type) {
    448     case EVENT_TYPE_FLOAT:
    449     /* Rely on union to translate elem.data.int32 into elem.data.float32 */
    450     /* FALLTHRU */
    451     case EVENT_TYPE_INT:
    452       elem.len = sizeof(int32_t);
    453       if ((pos + elem.len) > context->len) {
    454         elem.type = EVENT_TYPE_UNKNOWN;
    455         return elem;
    456       }
    457       elem.data.int32 = get4LE(&context->storage[pos]);
    458       /* common tangeable object suffix */
    459       pos += elem.len;
    460       elem.complete = !context->list_nest_depth && !context->count[0];
    461       if (!peek) {
    462         if (!context->count[context->list_nest_depth] ||
    463             !--(context->count[context->list_nest_depth])) {
    464           context->list_stop = true;
    465         }
    466         context->pos = pos;
    467       }
    468       return elem;
    469 
    470     case EVENT_TYPE_LONG:
    471       elem.len = sizeof(int64_t);
    472       if ((pos + elem.len) > context->len) {
    473         elem.type = EVENT_TYPE_UNKNOWN;
    474         return elem;
    475       }
    476       elem.data.int64 = get8LE(&context->storage[pos]);
    477       /* common tangeable object suffix */
    478       pos += elem.len;
    479       elem.complete = !context->list_nest_depth && !context->count[0];
    480       if (!peek) {
    481         if (!context->count[context->list_nest_depth] ||
    482             !--(context->count[context->list_nest_depth])) {
    483           context->list_stop = true;
    484         }
    485         context->pos = pos;
    486       }
    487       return elem;
    488 
    489     case EVENT_TYPE_STRING:
    490       if ((pos + sizeof(int32_t)) > context->len) {
    491         elem.type = EVENT_TYPE_UNKNOWN;
    492         elem.complete = true;
    493         return elem;
    494       }
    495       elem.len = get4LE(&context->storage[pos]);
    496       pos += sizeof(int32_t);
    497       if ((pos + elem.len) > context->len) {
    498         elem.len = context->len - pos; /* truncate string */
    499         elem.complete = true;
    500         if (!elem.len) {
    501           elem.type = EVENT_TYPE_UNKNOWN;
    502           return elem;
    503         }
    504       }
    505       elem.data.string = (char*)&context->storage[pos];
    506       /* common tangeable object suffix */
    507       pos += elem.len;
    508       elem.complete = !context->list_nest_depth && !context->count[0];
    509       if (!peek) {
    510         if (!context->count[context->list_nest_depth] ||
    511             !--(context->count[context->list_nest_depth])) {
    512           context->list_stop = true;
    513         }
    514         context->pos = pos;
    515       }
    516       return elem;
    517 
    518     case EVENT_TYPE_LIST:
    519       if ((pos + sizeof(uint8_t)) > context->len) {
    520         elem.type = EVENT_TYPE_UNKNOWN;
    521         elem.complete = true;
    522         return elem;
    523       }
    524       elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
    525       if (peek) {
    526         return elem;
    527       }
    528       if (context->count[context->list_nest_depth]) {
    529         context->count[context->list_nest_depth]--;
    530       }
    531       context->list_stop = !context->storage[pos];
    532       context->list_nest_depth++;
    533       if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
    534         context->count[context->list_nest_depth] = context->storage[pos];
    535       }
    536       context->pos = pos + sizeof(uint8_t);
    537       return elem;
    538 
    539     case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
    540       if (!peek) {
    541         context->pos = pos;
    542       }
    543       elem.type = EVENT_TYPE_UNKNOWN;
    544       elem.complete = !context->list_nest_depth;
    545       if (context->list_nest_depth > 0) {
    546         elem.type = EVENT_TYPE_LIST_STOP;
    547         if (!peek) {
    548           context->list_nest_depth--;
    549         }
    550       }
    551       return elem;
    552 
    553     default:
    554       elem.type = EVENT_TYPE_UNKNOWN;
    555       return elem;
    556   }
    557 }
    558 
    559 LIBLOG_ABI_PUBLIC android_log_list_element
    560 android_log_read_next(android_log_context ctx) {
    561   return android_log_read_next_internal(ctx, 0);
    562 }
    563 
    564 LIBLOG_ABI_PUBLIC android_log_list_element
    565 android_log_peek_next(android_log_context ctx) {
    566   return android_log_read_next_internal(ctx, 1);
    567 }
    568