log_event_list.c revision a3465441246ec339448e99847d518d81a17099b6
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
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(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 || (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
134static 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
141LIBLOG_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
165static 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
176LIBLOG_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
200LIBLOG_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
237LIBLOG_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
242LIBLOG_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
268LIBLOG_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 */
298LIBLOG_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
334LIBLOG_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 */
369static 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 */
376static 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 */
389static 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
559LIBLOG_ABI_PUBLIC android_log_list_element
560android_log_read_next(android_log_context ctx) {
561  return android_log_read_next_internal(ctx, 0);
562}
563
564LIBLOG_ABI_PUBLIC android_log_list_element
565android_log_peek_next(android_log_context ctx) {
566  return android_log_read_next_internal(ctx, 1);
567}
568
569LIBLOG_ABI_PUBLIC int android_log_writer_to_reader(android_log_context ctx) {
570  android_log_context_internal* context;
571
572  context = (android_log_context_internal*)ctx;
573
574  if (!context || context->read_write_flag != kAndroidLoggerWrite) {
575    return -EBADF;
576  }
577
578  context->len = context->pos;
579  context->storage[1] =
580      context
581          ->count[0];  // What does this do?!?! It's copied from the write func
582  context->pos = 0;
583  memset(context->count, 0, sizeof(context->count));
584  memset(context->list, 0, sizeof(context->list));
585  context->list_nest_depth = 0;
586  context->read_write_flag = kAndroidLoggerRead;
587  context->list_stop = false;
588
589  return 0;
590}
591