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