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