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