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 typedef 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 
create_android_logger(uint32_t tag)48 LIBLOG_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 
create_android_log_parser(const char * msg,size_t len)70 LIBLOG_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 
android_log_destroy(android_log_context * ctx)87 LIBLOG_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 
android_log_write_list_begin(android_log_context ctx)100 LIBLOG_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 
copy4LE(uint8_t * buf,uint32_t val)134 static 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 
android_log_write_int32(android_log_context ctx,int32_t value)141 LIBLOG_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 
copy8LE(uint8_t * buf,uint64_t val)165 static 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 
android_log_write_int64(android_log_context ctx,int64_t value)176 LIBLOG_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 
android_log_write_string8_len(android_log_context ctx,const char * value,size_t maxlen)200 LIBLOG_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 
android_log_write_string8(android_log_context ctx,const char * value)237 LIBLOG_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 
android_log_write_float32(android_log_context ctx,float value)242 LIBLOG_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 
android_log_write_list_end(android_log_context ctx)268 LIBLOG_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  */
android_log_write_list(android_log_context ctx,log_id_t id)298 LIBLOG_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)) {
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              : __android_log_security_bwrite(context->tag, msg, len);
330 }
331 
android_log_write_list_buffer(android_log_context ctx,const char ** buffer)332 LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
333                                                      const char** buffer) {
334   android_log_context_internal* context;
335   const char* msg;
336   ssize_t len;
337 
338   context = (android_log_context_internal*)ctx;
339   if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
340     return -EBADF;
341   }
342   if (context->list_nest_depth) {
343     return -EIO;
344   }
345   if (buffer == NULL) {
346     return -EFAULT;
347   }
348   /* NB: if there was overflow, then log is truncated. Nothing reported */
349   context->storage[1] = context->count[0];
350   len = context->len = context->pos;
351   msg = (const char*)context->storage;
352   /* it's not a list */
353   if (context->count[0] <= 1) {
354     len -= sizeof(uint8_t) + sizeof(uint8_t);
355     if (len < 0) {
356       len = 0;
357     }
358     msg += sizeof(uint8_t) + sizeof(uint8_t);
359   }
360   *buffer = msg;
361   return len;
362 }
363 
364 /*
365  * Extract a 4-byte value from a byte stream.
366  */
get4LE(const uint8_t * src)367 static inline uint32_t get4LE(const uint8_t* src) {
368   return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
369 }
370 
371 /*
372  * Extract an 8-byte value from a byte stream.
373  */
get8LE(const uint8_t * src)374 static inline uint64_t get8LE(const uint8_t* src) {
375   uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
376   uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
377   return ((uint64_t)high << 32) | (uint64_t)low;
378 }
379 
380 /*
381  * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
382  * If there is nothing to process, the complete field is set to non-zero. If
383  * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
384  * this and continues to call this function, the behavior is undefined
385  * (although it won't crash).
386  */
android_log_read_next_internal(android_log_context ctx,int peek)387 static android_log_list_element android_log_read_next_internal(
388     android_log_context ctx, int peek) {
389   android_log_list_element elem;
390   unsigned pos;
391   android_log_context_internal* context;
392 
393   context = (android_log_context_internal*)ctx;
394 
395   memset(&elem, 0, sizeof(elem));
396 
397   /* Nothing to parse from this context, so return complete. */
398   if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
399       (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
400       (context->count[context->list_nest_depth] >=
401        (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
402     elem.type = EVENT_TYPE_UNKNOWN;
403     if (context && (context->list_stop ||
404                     ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
405                      !context->count[context->list_nest_depth]))) {
406       elem.type = EVENT_TYPE_LIST_STOP;
407     }
408     elem.complete = true;
409     return elem;
410   }
411 
412   /*
413    * Use a different variable to update the position in case this
414    * operation is a "peek".
415    */
416   pos = context->pos;
417   if (context->list_stop) {
418     elem.type = EVENT_TYPE_LIST_STOP;
419     elem.complete = !context->count[0] &&
420                     (!context->list_nest_depth ||
421                      ((context->list_nest_depth == 1) && !context->count[1]));
422     if (!peek) {
423       /* Suck in superfluous stop */
424       if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
425         context->pos = pos + 1;
426       }
427       if (context->list_nest_depth) {
428         --context->list_nest_depth;
429         if (context->count[context->list_nest_depth]) {
430           context->list_stop = false;
431         }
432       } else {
433         context->list_stop = false;
434       }
435     }
436     return elem;
437   }
438   if ((pos + 1) > context->len) {
439     elem.type = EVENT_TYPE_UNKNOWN;
440     elem.complete = true;
441     return elem;
442   }
443 
444   elem.type = context->storage[pos++];
445   switch ((int)elem.type) {
446     case EVENT_TYPE_FLOAT:
447     /* Rely on union to translate elem.data.int32 into elem.data.float32 */
448     /* FALLTHRU */
449     case EVENT_TYPE_INT:
450       elem.len = sizeof(int32_t);
451       if ((pos + elem.len) > context->len) {
452         elem.type = EVENT_TYPE_UNKNOWN;
453         return elem;
454       }
455       elem.data.int32 = get4LE(&context->storage[pos]);
456       /* common tangeable object suffix */
457       pos += elem.len;
458       elem.complete = !context->list_nest_depth && !context->count[0];
459       if (!peek) {
460         if (!context->count[context->list_nest_depth] ||
461             !--(context->count[context->list_nest_depth])) {
462           context->list_stop = true;
463         }
464         context->pos = pos;
465       }
466       return elem;
467 
468     case EVENT_TYPE_LONG:
469       elem.len = sizeof(int64_t);
470       if ((pos + elem.len) > context->len) {
471         elem.type = EVENT_TYPE_UNKNOWN;
472         return elem;
473       }
474       elem.data.int64 = get8LE(&context->storage[pos]);
475       /* common tangeable object suffix */
476       pos += elem.len;
477       elem.complete = !context->list_nest_depth && !context->count[0];
478       if (!peek) {
479         if (!context->count[context->list_nest_depth] ||
480             !--(context->count[context->list_nest_depth])) {
481           context->list_stop = true;
482         }
483         context->pos = pos;
484       }
485       return elem;
486 
487     case EVENT_TYPE_STRING:
488       if ((pos + sizeof(int32_t)) > context->len) {
489         elem.type = EVENT_TYPE_UNKNOWN;
490         elem.complete = true;
491         return elem;
492       }
493       elem.len = get4LE(&context->storage[pos]);
494       pos += sizeof(int32_t);
495       if ((pos + elem.len) > context->len) {
496         elem.len = context->len - pos; /* truncate string */
497         elem.complete = true;
498         if (!elem.len) {
499           elem.type = EVENT_TYPE_UNKNOWN;
500           return elem;
501         }
502       }
503       elem.data.string = (char*)&context->storage[pos];
504       /* common tangeable object suffix */
505       pos += elem.len;
506       elem.complete = !context->list_nest_depth && !context->count[0];
507       if (!peek) {
508         if (!context->count[context->list_nest_depth] ||
509             !--(context->count[context->list_nest_depth])) {
510           context->list_stop = true;
511         }
512         context->pos = pos;
513       }
514       return elem;
515 
516     case EVENT_TYPE_LIST:
517       if ((pos + sizeof(uint8_t)) > context->len) {
518         elem.type = EVENT_TYPE_UNKNOWN;
519         elem.complete = true;
520         return elem;
521       }
522       elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
523       if (peek) {
524         return elem;
525       }
526       if (context->count[context->list_nest_depth]) {
527         context->count[context->list_nest_depth]--;
528       }
529       context->list_stop = !context->storage[pos];
530       context->list_nest_depth++;
531       if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
532         context->count[context->list_nest_depth] = context->storage[pos];
533       }
534       context->pos = pos + sizeof(uint8_t);
535       return elem;
536 
537     case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
538       if (!peek) {
539         context->pos = pos;
540       }
541       elem.type = EVENT_TYPE_UNKNOWN;
542       elem.complete = !context->list_nest_depth;
543       if (context->list_nest_depth > 0) {
544         elem.type = EVENT_TYPE_LIST_STOP;
545         if (!peek) {
546           context->list_nest_depth--;
547         }
548       }
549       return elem;
550 
551     default:
552       elem.type = EVENT_TYPE_UNKNOWN;
553       return elem;
554   }
555 }
556 
557 LIBLOG_ABI_PUBLIC android_log_list_element
android_log_read_next(android_log_context ctx)558 android_log_read_next(android_log_context ctx) {
559   return android_log_read_next_internal(ctx, 0);
560 }
561 
562 LIBLOG_ABI_PUBLIC android_log_list_element
android_log_peek_next(android_log_context ctx)563 android_log_peek_next(android_log_context ctx) {
564   return android_log_read_next_internal(ctx, 1);
565 }
566