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