1/* 2 * Copyright (C) 2007-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 <stdatomic.h> 19#include <stdlib.h> 20#include <string.h> 21#include <sys/time.h> 22 23#ifdef __BIONIC__ 24#include <android/set_abort_message.h> 25#endif 26 27#include <log/event_tag_map.h> 28#include <log/logd.h> 29#include <log/logger.h> 30#include <log/log_read.h> 31#include <private/android_filesystem_config.h> 32#include <private/android_logger.h> 33 34#include "config_write.h" 35#include "log_portability.h" 36#include "logger.h" 37 38#define LOG_BUF_SIZE 1024 39 40static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr); 41static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init; 42 43/* 44 * This is used by the C++ code to decide if it should write logs through 45 * the C code. Basically, if /dev/socket/logd is available, we're running in 46 * the simulator rather than a desktop tool and want to use the device. 47 */ 48static enum { 49 kLogUninitialized, kLogNotAvailable, kLogAvailable 50} g_log_status = kLogUninitialized; 51 52static int check_log_uid_permissions() 53{ 54#if defined(__BIONIC__) 55 uid_t uid = __android_log_uid(); 56 57 /* Matches clientHasLogCredentials() in logd */ 58 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { 59 uid = geteuid(); 60 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { 61 gid_t gid = getgid(); 62 if ((gid != AID_SYSTEM) && 63 (gid != AID_ROOT) && 64 (gid != AID_LOG)) { 65 gid = getegid(); 66 if ((gid != AID_SYSTEM) && 67 (gid != AID_ROOT) && 68 (gid != AID_LOG)) { 69 int num_groups; 70 gid_t *groups; 71 72 num_groups = getgroups(0, NULL); 73 if (num_groups <= 0) { 74 return -EPERM; 75 } 76 groups = calloc(num_groups, sizeof(gid_t)); 77 if (!groups) { 78 return -ENOMEM; 79 } 80 num_groups = getgroups(num_groups, groups); 81 while (num_groups > 0) { 82 if (groups[num_groups - 1] == AID_LOG) { 83 break; 84 } 85 --num_groups; 86 } 87 free(groups); 88 if (num_groups <= 0) { 89 return -EPERM; 90 } 91 } 92 } 93 } 94 } 95#endif 96 return 0; 97} 98 99static void __android_log_cache_available( 100 struct android_log_transport_write *node) 101{ 102 size_t i; 103 104 if (node->logMask) { 105 return; 106 } 107 108 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { 109 if (node->write && 110 (i != LOG_ID_KERNEL) && 111 ((i != LOG_ID_SECURITY) || 112 (check_log_uid_permissions() == 0)) && 113 (!node->available || ((*node->available)(i) >= 0))) { 114 node->logMask |= 1 << i; 115 } 116 } 117} 118 119LIBLOG_ABI_PUBLIC int __android_log_dev_available() 120{ 121 struct android_log_transport_write *node; 122 123 if (list_empty(&__android_log_transport_write)) { 124 return kLogUninitialized; 125 } 126 127 write_transport_for_each(node, &__android_log_transport_write) { 128 __android_log_cache_available(node); 129 if (node->logMask) { 130 return kLogAvailable; 131 } 132 } 133 return kLogNotAvailable; 134} 135/* 136 * Release any logger resources. A new log write will immediately re-acquire. 137 */ 138LIBLOG_ABI_PUBLIC void __android_log_close() 139{ 140 struct android_log_transport_write *transport; 141 142 __android_log_lock(); 143 144 write_to_log = __write_to_log_init; 145 146 /* 147 * Threads that are actively writing at this point are not held back 148 * by a lock and are at risk of dropping the messages with a return code 149 * -EBADF. Prefer to return error code than add the overhead of a lock to 150 * each log writing call to guarantee delivery. In addition, anyone 151 * calling this is doing so to release the logging resources and shut down, 152 * for them to do so with outstanding log requests in other threads is a 153 * disengenuous use of this function. 154 */ 155 156 write_transport_for_each(transport, &__android_log_persist_write) { 157 if (transport->close) { 158 (*transport->close)(); 159 } 160 } 161 162 write_transport_for_each(transport, &__android_log_transport_write) { 163 if (transport->close) { 164 (*transport->close)(); 165 } 166 } 167 168 __android_log_unlock(); 169} 170 171/* log_init_lock assumed */ 172static int __write_to_log_initialize() 173{ 174 struct android_log_transport_write *transport; 175 struct listnode *n; 176 int i = 0, ret = 0; 177 178 __android_log_config_write(); 179 write_transport_for_each_safe(transport, n, &__android_log_transport_write) { 180 __android_log_cache_available(transport); 181 if (!transport->logMask) { 182 list_remove(&transport->node); 183 continue; 184 } 185 if (!transport->open || ((*transport->open)() < 0)) { 186 if (transport->close) { 187 (*transport->close)(); 188 } 189 list_remove(&transport->node); 190 continue; 191 } 192 ++ret; 193 } 194 write_transport_for_each_safe(transport, n, &__android_log_persist_write) { 195 __android_log_cache_available(transport); 196 if (!transport->logMask) { 197 list_remove(&transport->node); 198 continue; 199 } 200 if (!transport->open || ((*transport->open)() < 0)) { 201 if (transport->close) { 202 (*transport->close)(); 203 } 204 list_remove(&transport->node); 205 continue; 206 } 207 ++i; 208 } 209 if (!ret && !i) { 210 return -ENODEV; 211 } 212 213 return ret; 214} 215 216/* 217 * Extract a 4-byte value from a byte stream. le32toh open coded 218 */ 219static inline uint32_t get4LE(const uint8_t* src) 220{ 221 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 222} 223 224static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) 225{ 226 struct android_log_transport_write *node; 227 int ret; 228 struct timespec ts; 229 size_t len, i; 230 231 for (len = i = 0; i < nr; ++i) { 232 len += vec[i].iov_len; 233 } 234 if (!len) { 235 return -EINVAL; 236 } 237 238#if defined(__BIONIC__) 239 if (log_id == LOG_ID_SECURITY) { 240 if (vec[0].iov_len < 4) { 241 return -EINVAL; 242 } 243 244 ret = check_log_uid_permissions(); 245 if (ret < 0) { 246 return ret; 247 } 248 if (!__android_log_security()) { 249 /* If only we could reset downstream logd counter */ 250 return -EPERM; 251 } 252 } else if (log_id == LOG_ID_EVENTS) { 253 static atomic_uintptr_t map; 254 const char *tag; 255 EventTagMap *m, *f; 256 257 if (vec[0].iov_len < 4) { 258 return -EINVAL; 259 } 260 261 tag = NULL; 262 f = NULL; 263 m = (EventTagMap *)atomic_load(&map); 264 265 if (!m) { 266 ret = __android_log_trylock(); 267 m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */ 268 if (!m) { 269 m = android_openEventTagMap(EVENT_TAG_MAP_FILE); 270 if (ret) { /* trylock failed, use local copy, mark for close */ 271 f = m; 272 } else { 273 if (!m) { /* One chance to open map file */ 274 m = (EventTagMap *)(uintptr_t)-1LL; 275 } 276 atomic_store(&map, (uintptr_t)m); 277 } 278 } 279 if (!ret) { /* trylock succeeded, unlock */ 280 __android_log_unlock(); 281 } 282 } 283 if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) { 284 tag = android_lookupEventTag(m, get4LE(vec[0].iov_base)); 285 } 286 ret = __android_log_is_loggable(ANDROID_LOG_INFO, 287 tag, 288 ANDROID_LOG_VERBOSE); 289 if (f) { /* local copy marked for close */ 290 android_closeEventTagMap(f); 291 } 292 if (!ret) { 293 return -EPERM; 294 } 295 } else { 296 /* Validate the incoming tag, tag content can not split across iovec */ 297 char prio = ANDROID_LOG_VERBOSE; 298 const char *tag = vec[0].iov_base; 299 size_t len = vec[0].iov_len; 300 if (!tag) { 301 len = 0; 302 } 303 if (len > 0) { 304 prio = *tag; 305 if (len > 1) { 306 --len; 307 ++tag; 308 } else { 309 len = vec[1].iov_len; 310 tag = ((const char *)vec[1].iov_base); 311 if (!tag) { 312 len = 0; 313 } 314 } 315 } 316 /* tag must be nul terminated */ 317 if (strnlen(tag, len) >= len) { 318 tag = NULL; 319 } 320 321 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { 322 return -EPERM; 323 } 324 } 325 326 clock_gettime(android_log_clockid(), &ts); 327#else 328 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */ 329 { 330 struct timeval tv; 331 gettimeofday(&tv, NULL); 332 ts.tv_sec = tv.tv_sec; 333 ts.tv_nsec = tv.tv_usec * 1000; 334 } 335#endif 336 337 ret = 0; 338 i = 1 << log_id; 339 write_transport_for_each(node, &__android_log_transport_write) { 340 if (node->logMask & i) { 341 ssize_t retval; 342 retval = (*node->write)(log_id, &ts, vec, nr); 343 if (ret >= 0) { 344 ret = retval; 345 } 346 } 347 } 348 349 write_transport_for_each(node, &__android_log_persist_write) { 350 if (node->logMask & i) { 351 (void)(*node->write)(log_id, &ts, vec, nr); 352 } 353 } 354 355 return ret; 356} 357 358static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) 359{ 360 __android_log_lock(); 361 362 if (write_to_log == __write_to_log_init) { 363 int ret; 364 365 ret = __write_to_log_initialize(); 366 if (ret < 0) { 367 __android_log_unlock(); 368 if (!list_empty(&__android_log_persist_write)) { 369 __write_to_log_daemon(log_id, vec, nr); 370 } 371 return ret; 372 } 373 374 write_to_log = __write_to_log_daemon; 375 } 376 377 __android_log_unlock(); 378 379 return write_to_log(log_id, vec, nr); 380} 381 382LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag, 383 const char *msg) 384{ 385 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg); 386} 387 388LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio, 389 const char *tag, const char *msg) 390{ 391 struct iovec vec[3]; 392 char tmp_tag[32]; 393 394 if (!tag) 395 tag = ""; 396 397 /* XXX: This needs to go! */ 398 if ((bufID != LOG_ID_RADIO) && 399 (!strcmp(tag, "HTC_RIL") || 400 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */ 401 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */ 402 !strcmp(tag, "AT") || 403 !strcmp(tag, "GSM") || 404 !strcmp(tag, "STK") || 405 !strcmp(tag, "CDMA") || 406 !strcmp(tag, "PHONE") || 407 !strcmp(tag, "SMS"))) { 408 bufID = LOG_ID_RADIO; 409 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */ 410 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag); 411 tag = tmp_tag; 412 } 413 414#if __BIONIC__ 415 if (prio == ANDROID_LOG_FATAL) { 416 android_set_abort_message(msg); 417 } 418#endif 419 420 vec[0].iov_base = (unsigned char *)&prio; 421 vec[0].iov_len = 1; 422 vec[1].iov_base = (void *)tag; 423 vec[1].iov_len = strlen(tag) + 1; 424 vec[2].iov_base = (void *)msg; 425 vec[2].iov_len = strlen(msg) + 1; 426 427 return write_to_log(bufID, vec, 3); 428} 429 430LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag, 431 const char *fmt, va_list ap) 432{ 433 char buf[LOG_BUF_SIZE]; 434 435 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 436 437 return __android_log_write(prio, tag, buf); 438} 439 440LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag, 441 const char *fmt, ...) 442{ 443 va_list ap; 444 char buf[LOG_BUF_SIZE]; 445 446 va_start(ap, fmt); 447 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 448 va_end(ap); 449 450 return __android_log_write(prio, tag, buf); 451} 452 453LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio, 454 const char *tag, 455 const char *fmt, ...) 456{ 457 va_list ap; 458 char buf[LOG_BUF_SIZE]; 459 460 va_start(ap, fmt); 461 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 462 va_end(ap); 463 464 return __android_log_buf_write(bufID, prio, tag, buf); 465} 466 467LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag, 468 const char *fmt, ...) 469{ 470 char buf[LOG_BUF_SIZE]; 471 472 if (fmt) { 473 va_list ap; 474 va_start(ap, fmt); 475 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 476 va_end(ap); 477 } else { 478 /* Msg not provided, log condition. N.B. Do not use cond directly as 479 * format string as it could contain spurious '%' syntax (e.g. 480 * "%d" in "blocks%devs == 0"). 481 */ 482 if (cond) 483 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond); 484 else 485 strcpy(buf, "Unspecified assertion failed"); 486 } 487 488 __android_log_write(ANDROID_LOG_FATAL, tag, buf); 489 abort(); /* abort so we have a chance to debug the situation */ 490 /* NOTREACHED */ 491} 492 493LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, 494 const void *payload, size_t len) 495{ 496 struct iovec vec[2]; 497 498 vec[0].iov_base = &tag; 499 vec[0].iov_len = sizeof(tag); 500 vec[1].iov_base = (void*)payload; 501 vec[1].iov_len = len; 502 503 return write_to_log(LOG_ID_EVENTS, vec, 2); 504} 505 506LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag, 507 const void *payload, 508 size_t len) 509{ 510 struct iovec vec[2]; 511 512 vec[0].iov_base = &tag; 513 vec[0].iov_len = sizeof(tag); 514 vec[1].iov_base = (void*)payload; 515 vec[1].iov_len = len; 516 517 return write_to_log(LOG_ID_SECURITY, vec, 2); 518} 519 520/* 521 * Like __android_log_bwrite, but takes the type as well. Doesn't work 522 * for the general case where we're generating lists of stuff, but very 523 * handy if we just want to dump an integer into the log. 524 */ 525LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type, 526 const void *payload, size_t len) 527{ 528 struct iovec vec[3]; 529 530 vec[0].iov_base = &tag; 531 vec[0].iov_len = sizeof(tag); 532 vec[1].iov_base = &type; 533 vec[1].iov_len = sizeof(type); 534 vec[2].iov_base = (void*)payload; 535 vec[2].iov_len = len; 536 537 return write_to_log(LOG_ID_EVENTS, vec, 3); 538} 539 540/* 541 * Like __android_log_bwrite, but used for writing strings to the 542 * event log. 543 */ 544LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload) 545{ 546 struct iovec vec[4]; 547 char type = EVENT_TYPE_STRING; 548 uint32_t len = strlen(payload); 549 550 vec[0].iov_base = &tag; 551 vec[0].iov_len = sizeof(tag); 552 vec[1].iov_base = &type; 553 vec[1].iov_len = sizeof(type); 554 vec[2].iov_base = &len; 555 vec[2].iov_len = sizeof(len); 556 vec[3].iov_base = (void*)payload; 557 vec[3].iov_len = len; 558 559 return write_to_log(LOG_ID_EVENTS, vec, 4); 560} 561 562/* 563 * Like __android_log_security_bwrite, but used for writing strings to the 564 * security log. 565 */ 566LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag, 567 const char *payload) 568{ 569 struct iovec vec[4]; 570 char type = EVENT_TYPE_STRING; 571 uint32_t len = strlen(payload); 572 573 vec[0].iov_base = &tag; 574 vec[0].iov_len = sizeof(tag); 575 vec[1].iov_base = &type; 576 vec[1].iov_len = sizeof(type); 577 vec[2].iov_base = &len; 578 vec[2].iov_len = sizeof(len); 579 vec[3].iov_base = (void*)payload; 580 vec[3].iov_len = len; 581 582 return write_to_log(LOG_ID_SECURITY, vec, 4); 583} 584