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