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