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