log_event_list.c revision 6584d0a35ab7722bdc6590525dee29f72f0ec576
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 <android/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
32typedef 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
48LIBLOG_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
70LIBLOG_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
88LIBLOG_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
101LIBLOG_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
136static 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
144LIBLOG_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
168static 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
180LIBLOG_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
204LIBLOG_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
241LIBLOG_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
246LIBLOG_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
272LIBLOG_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 */
302LIBLOG_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 */
339static 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 */
347static 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 */
361static 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
531LIBLOG_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
536LIBLOG_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