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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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)) { 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 : __android_log_security_bwrite(context->tag, msg, len); 330 } 331 332 LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx, 333 const char** buffer) { 334 android_log_context_internal* context; 335 const char* msg; 336 ssize_t len; 337 338 context = (android_log_context_internal*)ctx; 339 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 340 return -EBADF; 341 } 342 if (context->list_nest_depth) { 343 return -EIO; 344 } 345 if (buffer == NULL) { 346 return -EFAULT; 347 } 348 /* NB: if there was overflow, then log is truncated. Nothing reported */ 349 context->storage[1] = context->count[0]; 350 len = context->len = context->pos; 351 msg = (const char*)context->storage; 352 /* it's not a list */ 353 if (context->count[0] <= 1) { 354 len -= sizeof(uint8_t) + sizeof(uint8_t); 355 if (len < 0) { 356 len = 0; 357 } 358 msg += sizeof(uint8_t) + sizeof(uint8_t); 359 } 360 *buffer = msg; 361 return len; 362 } 363 364 /* 365 * Extract a 4-byte value from a byte stream. 366 */ 367 static inline uint32_t get4LE(const uint8_t* src) { 368 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 369 } 370 371 /* 372 * Extract an 8-byte value from a byte stream. 373 */ 374 static inline uint64_t get8LE(const uint8_t* src) { 375 uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 376 uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); 377 return ((uint64_t)high << 32) | (uint64_t)low; 378 } 379 380 /* 381 * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type. 382 * If there is nothing to process, the complete field is set to non-zero. If 383 * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check 384 * this and continues to call this function, the behavior is undefined 385 * (although it won't crash). 386 */ 387 static android_log_list_element android_log_read_next_internal( 388 android_log_context ctx, int peek) { 389 android_log_list_element elem; 390 unsigned pos; 391 android_log_context_internal* context; 392 393 context = (android_log_context_internal*)ctx; 394 395 memset(&elem, 0, sizeof(elem)); 396 397 /* Nothing to parse from this context, so return complete. */ 398 if (!context || (kAndroidLoggerRead != context->read_write_flag) || 399 (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) || 400 (context->count[context->list_nest_depth] >= 401 (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) { 402 elem.type = EVENT_TYPE_UNKNOWN; 403 if (context && (context->list_stop || 404 ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) && 405 !context->count[context->list_nest_depth]))) { 406 elem.type = EVENT_TYPE_LIST_STOP; 407 } 408 elem.complete = true; 409 return elem; 410 } 411 412 /* 413 * Use a different variable to update the position in case this 414 * operation is a "peek". 415 */ 416 pos = context->pos; 417 if (context->list_stop) { 418 elem.type = EVENT_TYPE_LIST_STOP; 419 elem.complete = !context->count[0] && 420 (!context->list_nest_depth || 421 ((context->list_nest_depth == 1) && !context->count[1])); 422 if (!peek) { 423 /* Suck in superfluous stop */ 424 if (context->storage[pos] == EVENT_TYPE_LIST_STOP) { 425 context->pos = pos + 1; 426 } 427 if (context->list_nest_depth) { 428 --context->list_nest_depth; 429 if (context->count[context->list_nest_depth]) { 430 context->list_stop = false; 431 } 432 } else { 433 context->list_stop = false; 434 } 435 } 436 return elem; 437 } 438 if ((pos + 1) > context->len) { 439 elem.type = EVENT_TYPE_UNKNOWN; 440 elem.complete = true; 441 return elem; 442 } 443 444 elem.type = context->storage[pos++]; 445 switch ((int)elem.type) { 446 case EVENT_TYPE_FLOAT: 447 /* Rely on union to translate elem.data.int32 into elem.data.float32 */ 448 /* FALLTHRU */ 449 case EVENT_TYPE_INT: 450 elem.len = sizeof(int32_t); 451 if ((pos + elem.len) > context->len) { 452 elem.type = EVENT_TYPE_UNKNOWN; 453 return elem; 454 } 455 elem.data.int32 = get4LE(&context->storage[pos]); 456 /* common tangeable object suffix */ 457 pos += elem.len; 458 elem.complete = !context->list_nest_depth && !context->count[0]; 459 if (!peek) { 460 if (!context->count[context->list_nest_depth] || 461 !--(context->count[context->list_nest_depth])) { 462 context->list_stop = true; 463 } 464 context->pos = pos; 465 } 466 return elem; 467 468 case EVENT_TYPE_LONG: 469 elem.len = sizeof(int64_t); 470 if ((pos + elem.len) > context->len) { 471 elem.type = EVENT_TYPE_UNKNOWN; 472 return elem; 473 } 474 elem.data.int64 = get8LE(&context->storage[pos]); 475 /* common tangeable object suffix */ 476 pos += elem.len; 477 elem.complete = !context->list_nest_depth && !context->count[0]; 478 if (!peek) { 479 if (!context->count[context->list_nest_depth] || 480 !--(context->count[context->list_nest_depth])) { 481 context->list_stop = true; 482 } 483 context->pos = pos; 484 } 485 return elem; 486 487 case EVENT_TYPE_STRING: 488 if ((pos + sizeof(int32_t)) > context->len) { 489 elem.type = EVENT_TYPE_UNKNOWN; 490 elem.complete = true; 491 return elem; 492 } 493 elem.len = get4LE(&context->storage[pos]); 494 pos += sizeof(int32_t); 495 if ((pos + elem.len) > context->len) { 496 elem.len = context->len - pos; /* truncate string */ 497 elem.complete = true; 498 if (!elem.len) { 499 elem.type = EVENT_TYPE_UNKNOWN; 500 return elem; 501 } 502 } 503 elem.data.string = (char*)&context->storage[pos]; 504 /* common tangeable object suffix */ 505 pos += elem.len; 506 elem.complete = !context->list_nest_depth && !context->count[0]; 507 if (!peek) { 508 if (!context->count[context->list_nest_depth] || 509 !--(context->count[context->list_nest_depth])) { 510 context->list_stop = true; 511 } 512 context->pos = pos; 513 } 514 return elem; 515 516 case EVENT_TYPE_LIST: 517 if ((pos + sizeof(uint8_t)) > context->len) { 518 elem.type = EVENT_TYPE_UNKNOWN; 519 elem.complete = true; 520 return elem; 521 } 522 elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH; 523 if (peek) { 524 return elem; 525 } 526 if (context->count[context->list_nest_depth]) { 527 context->count[context->list_nest_depth]--; 528 } 529 context->list_stop = !context->storage[pos]; 530 context->list_nest_depth++; 531 if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) { 532 context->count[context->list_nest_depth] = context->storage[pos]; 533 } 534 context->pos = pos + sizeof(uint8_t); 535 return elem; 536 537 case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */ 538 if (!peek) { 539 context->pos = pos; 540 } 541 elem.type = EVENT_TYPE_UNKNOWN; 542 elem.complete = !context->list_nest_depth; 543 if (context->list_nest_depth > 0) { 544 elem.type = EVENT_TYPE_LIST_STOP; 545 if (!peek) { 546 context->list_nest_depth--; 547 } 548 } 549 return elem; 550 551 default: 552 elem.type = EVENT_TYPE_UNKNOWN; 553 return elem; 554 } 555 } 556 557 LIBLOG_ABI_PUBLIC android_log_list_element 558 android_log_read_next(android_log_context ctx) { 559 return android_log_read_next_internal(ctx, 0); 560 } 561 562 LIBLOG_ABI_PUBLIC android_log_list_element 563 android_log_peek_next(android_log_context ctx) { 564 return android_log_read_next_internal(ctx, 1); 565 } 566