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)) {
    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              : __android_log_security_bwrite(context->tag, msg, len);
    330 }
    331 
    332 LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
    333                                                      const char** buffer) {
    334   android_log_context_internal* context;
    335   const char* msg;
    336   ssize_t len;
    337 
    338   context = (android_log_context_internal*)ctx;
    339   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
    340     return -EBADF;
    341   }
    342   if (context->list_nest_depth) {
    343     return -EIO;
    344   }
    345   if (buffer == NULL) {
    346     return -EFAULT;
    347   }
    348   /* NB: if there was overflow, then log is truncated. Nothing reported */
    349   context->storage[1] = context->count[0];
    350   len = context->len = context->pos;
    351   msg = (const char*)context->storage;
    352   /* it's not a list */
    353   if (context->count[0] <= 1) {
    354     len -= sizeof(uint8_t) + sizeof(uint8_t);
    355     if (len < 0) {
    356       len = 0;
    357     }
    358     msg += sizeof(uint8_t) + sizeof(uint8_t);
    359   }
    360   *buffer = msg;
    361   return len;
    362 }
    363 
    364 /*
    365  * Extract a 4-byte value from a byte stream.
    366  */
    367 static inline uint32_t get4LE(const uint8_t* src) {
    368   return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
    369 }
    370 
    371 /*
    372  * Extract an 8-byte value from a byte stream.
    373  */
    374 static inline uint64_t get8LE(const uint8_t* src) {
    375   uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
    376   uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
    377   return ((uint64_t)high << 32) | (uint64_t)low;
    378 }
    379 
    380 /*
    381  * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
    382  * If there is nothing to process, the complete field is set to non-zero. If
    383  * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
    384  * this and continues to call this function, the behavior is undefined
    385  * (although it won't crash).
    386  */
    387 static android_log_list_element android_log_read_next_internal(
    388     android_log_context ctx, int peek) {
    389   android_log_list_element elem;
    390   unsigned pos;
    391   android_log_context_internal* context;
    392 
    393   context = (android_log_context_internal*)ctx;
    394 
    395   memset(&elem, 0, sizeof(elem));
    396 
    397   /* Nothing to parse from this context, so return complete. */
    398   if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
    399       (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
    400       (context->count[context->list_nest_depth] >=
    401        (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
    402     elem.type = EVENT_TYPE_UNKNOWN;
    403     if (context && (context->list_stop ||
    404                     ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
    405                      !context->count[context->list_nest_depth]))) {
    406       elem.type = EVENT_TYPE_LIST_STOP;
    407     }
    408     elem.complete = true;
    409     return elem;
    410   }
    411 
    412   /*
    413    * Use a different variable to update the position in case this
    414    * operation is a "peek".
    415    */
    416   pos = context->pos;
    417   if (context->list_stop) {
    418     elem.type = EVENT_TYPE_LIST_STOP;
    419     elem.complete = !context->count[0] &&
    420                     (!context->list_nest_depth ||
    421                      ((context->list_nest_depth == 1) && !context->count[1]));
    422     if (!peek) {
    423       /* Suck in superfluous stop */
    424       if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
    425         context->pos = pos + 1;
    426       }
    427       if (context->list_nest_depth) {
    428         --context->list_nest_depth;
    429         if (context->count[context->list_nest_depth]) {
    430           context->list_stop = false;
    431         }
    432       } else {
    433         context->list_stop = false;
    434       }
    435     }
    436     return elem;
    437   }
    438   if ((pos + 1) > context->len) {
    439     elem.type = EVENT_TYPE_UNKNOWN;
    440     elem.complete = true;
    441     return elem;
    442   }
    443 
    444   elem.type = context->storage[pos++];
    445   switch ((int)elem.type) {
    446     case EVENT_TYPE_FLOAT:
    447     /* Rely on union to translate elem.data.int32 into elem.data.float32 */
    448     /* FALLTHRU */
    449     case EVENT_TYPE_INT:
    450       elem.len = sizeof(int32_t);
    451       if ((pos + elem.len) > context->len) {
    452         elem.type = EVENT_TYPE_UNKNOWN;
    453         return elem;
    454       }
    455       elem.data.int32 = get4LE(&context->storage[pos]);
    456       /* common tangeable object suffix */
    457       pos += elem.len;
    458       elem.complete = !context->list_nest_depth && !context->count[0];
    459       if (!peek) {
    460         if (!context->count[context->list_nest_depth] ||
    461             !--(context->count[context->list_nest_depth])) {
    462           context->list_stop = true;
    463         }
    464         context->pos = pos;
    465       }
    466       return elem;
    467 
    468     case EVENT_TYPE_LONG:
    469       elem.len = sizeof(int64_t);
    470       if ((pos + elem.len) > context->len) {
    471         elem.type = EVENT_TYPE_UNKNOWN;
    472         return elem;
    473       }
    474       elem.data.int64 = get8LE(&context->storage[pos]);
    475       /* common tangeable object suffix */
    476       pos += elem.len;
    477       elem.complete = !context->list_nest_depth && !context->count[0];
    478       if (!peek) {
    479         if (!context->count[context->list_nest_depth] ||
    480             !--(context->count[context->list_nest_depth])) {
    481           context->list_stop = true;
    482         }
    483         context->pos = pos;
    484       }
    485       return elem;
    486 
    487     case EVENT_TYPE_STRING:
    488       if ((pos + sizeof(int32_t)) > context->len) {
    489         elem.type = EVENT_TYPE_UNKNOWN;
    490         elem.complete = true;
    491         return elem;
    492       }
    493       elem.len = get4LE(&context->storage[pos]);
    494       pos += sizeof(int32_t);
    495       if ((pos + elem.len) > context->len) {
    496         elem.len = context->len - pos; /* truncate string */
    497         elem.complete = true;
    498         if (!elem.len) {
    499           elem.type = EVENT_TYPE_UNKNOWN;
    500           return elem;
    501         }
    502       }
    503       elem.data.string = (char*)&context->storage[pos];
    504       /* common tangeable object suffix */
    505       pos += elem.len;
    506       elem.complete = !context->list_nest_depth && !context->count[0];
    507       if (!peek) {
    508         if (!context->count[context->list_nest_depth] ||
    509             !--(context->count[context->list_nest_depth])) {
    510           context->list_stop = true;
    511         }
    512         context->pos = pos;
    513       }
    514       return elem;
    515 
    516     case EVENT_TYPE_LIST:
    517       if ((pos + sizeof(uint8_t)) > context->len) {
    518         elem.type = EVENT_TYPE_UNKNOWN;
    519         elem.complete = true;
    520         return elem;
    521       }
    522       elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
    523       if (peek) {
    524         return elem;
    525       }
    526       if (context->count[context->list_nest_depth]) {
    527         context->count[context->list_nest_depth]--;
    528       }
    529       context->list_stop = !context->storage[pos];
    530       context->list_nest_depth++;
    531       if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
    532         context->count[context->list_nest_depth] = context->storage[pos];
    533       }
    534       context->pos = pos + sizeof(uint8_t);
    535       return elem;
    536 
    537     case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
    538       if (!peek) {
    539         context->pos = pos;
    540       }
    541       elem.type = EVENT_TYPE_UNKNOWN;
    542       elem.complete = !context->list_nest_depth;
    543       if (context->list_nest_depth > 0) {
    544         elem.type = EVENT_TYPE_LIST_STOP;
    545         if (!peek) {
    546           context->list_nest_depth--;
    547         }
    548       }
    549       return elem;
    550 
    551     default:
    552       elem.type = EVENT_TYPE_UNKNOWN;
    553       return elem;
    554   }
    555 }
    556 
    557 LIBLOG_ABI_PUBLIC android_log_list_element
    558 android_log_read_next(android_log_context ctx) {
    559   return android_log_read_next_internal(ctx, 0);
    560 }
    561 
    562 LIBLOG_ABI_PUBLIC android_log_list_element
    563 android_log_peek_next(android_log_context ctx) {
    564   return android_log_read_next_internal(ctx, 1);
    565 }
    566