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