• 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 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) && (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 
android_log_write_list_buffer(android_log_context ctx,const char ** buffer)334 LIBLOG_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  */
get4LE(const uint8_t * src)369 static 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  */
get8LE(const uint8_t * src)376 static 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  */
android_log_read_next_internal(android_log_context ctx,int peek)389 static 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 
559 LIBLOG_ABI_PUBLIC android_log_list_element
android_log_read_next(android_log_context ctx)560 android_log_read_next(android_log_context ctx) {
561   return android_log_read_next_internal(ctx, 0);
562 }
563 
564 LIBLOG_ABI_PUBLIC android_log_list_element
android_log_peek_next(android_log_context ctx)565 android_log_peek_next(android_log_context ctx) {
566   return android_log_read_next_internal(ctx, 1);
567 }
568