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