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