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 40 static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr); 41 static 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 */ 48 static enum { 49 kLogUninitialized, kLogNotAvailable, kLogAvailable 50 } g_log_status = kLogUninitialized; 51 52 static 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 99 static 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 119 LIBLOG_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 /* log_init_lock assumed */ 137 static int __write_to_log_initialize() 138 { 139 struct android_log_transport_write *transport; 140 struct listnode *n; 141 int i = 0, ret = 0; 142 143 __android_log_config_write(); 144 write_transport_for_each_safe(transport, n, &__android_log_transport_write) { 145 __android_log_cache_available(transport); 146 if (!transport->logMask) { 147 list_remove(&transport->node); 148 continue; 149 } 150 if (!transport->open || ((*transport->open)() < 0)) { 151 if (transport->close) { 152 (*transport->close)(); 153 } 154 list_remove(&transport->node); 155 continue; 156 } 157 ++ret; 158 } 159 write_transport_for_each_safe(transport, n, &__android_log_persist_write) { 160 __android_log_cache_available(transport); 161 if (!transport->logMask) { 162 list_remove(&transport->node); 163 continue; 164 } 165 if (!transport->open || ((*transport->open)() < 0)) { 166 if (transport->close) { 167 (*transport->close)(); 168 } 169 list_remove(&transport->node); 170 continue; 171 } 172 ++i; 173 } 174 if (!ret && !i) { 175 return -ENODEV; 176 } 177 178 return ret; 179 } 180 181 /* 182 * Extract a 4-byte value from a byte stream. le32toh open coded 183 */ 184 static inline uint32_t get4LE(const uint8_t* src) 185 { 186 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 187 } 188 189 static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) 190 { 191 struct android_log_transport_write *node; 192 int ret; 193 struct timespec ts; 194 size_t len, i; 195 196 for (len = i = 0; i < nr; ++i) { 197 len += vec[i].iov_len; 198 } 199 if (!len) { 200 return -EINVAL; 201 } 202 203 #if defined(__BIONIC__) 204 if (log_id == LOG_ID_SECURITY) { 205 if (vec[0].iov_len < 4) { 206 return -EINVAL; 207 } 208 209 ret = check_log_uid_permissions(); 210 if (ret < 0) { 211 return ret; 212 } 213 if (!__android_log_security()) { 214 /* If only we could reset downstream logd counter */ 215 return -EPERM; 216 } 217 } else if (log_id == LOG_ID_EVENTS) { 218 static atomic_uintptr_t map; 219 const char *tag; 220 EventTagMap *m, *f; 221 222 if (vec[0].iov_len < 4) { 223 return -EINVAL; 224 } 225 226 tag = NULL; 227 f = NULL; 228 m = (EventTagMap *)atomic_load(&map); 229 230 if (!m) { 231 ret = __android_log_trylock(); 232 m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */ 233 if (!m) { 234 m = android_openEventTagMap(EVENT_TAG_MAP_FILE); 235 if (ret) { /* trylock failed, use local copy, mark for close */ 236 f = m; 237 } else { 238 if (!m) { /* One chance to open map file */ 239 m = (EventTagMap *)(uintptr_t)-1LL; 240 } 241 atomic_store(&map, (uintptr_t)m); 242 } 243 } 244 if (!ret) { /* trylock succeeded, unlock */ 245 __android_log_unlock(); 246 } 247 } 248 if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) { 249 tag = android_lookupEventTag(m, get4LE(vec[0].iov_base)); 250 } 251 ret = __android_log_is_loggable(ANDROID_LOG_INFO, 252 tag, 253 ANDROID_LOG_VERBOSE); 254 if (f) { /* local copy marked for close */ 255 android_closeEventTagMap(f); 256 } 257 if (!ret) { 258 return -EPERM; 259 } 260 } else { 261 /* Validate the incoming tag, tag content can not split across iovec */ 262 char prio = ANDROID_LOG_VERBOSE; 263 const char *tag = vec[0].iov_base; 264 size_t len = vec[0].iov_len; 265 if (!tag) { 266 len = 0; 267 } 268 if (len > 0) { 269 prio = *tag; 270 if (len > 1) { 271 --len; 272 ++tag; 273 } else { 274 len = vec[1].iov_len; 275 tag = ((const char *)vec[1].iov_base); 276 if (!tag) { 277 len = 0; 278 } 279 } 280 } 281 /* tag must be nul terminated */ 282 if (strnlen(tag, len) >= len) { 283 tag = NULL; 284 } 285 286 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { 287 return -EPERM; 288 } 289 } 290 291 clock_gettime(android_log_clockid(), &ts); 292 #else 293 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */ 294 { 295 struct timeval tv; 296 gettimeofday(&tv, NULL); 297 ts.tv_sec = tv.tv_sec; 298 ts.tv_nsec = tv.tv_usec * 1000; 299 } 300 #endif 301 302 ret = 0; 303 i = 1 << log_id; 304 write_transport_for_each(node, &__android_log_transport_write) { 305 if (node->logMask & i) { 306 ssize_t retval; 307 retval = (*node->write)(log_id, &ts, vec, nr); 308 if (ret >= 0) { 309 ret = retval; 310 } 311 } 312 } 313 314 write_transport_for_each(node, &__android_log_persist_write) { 315 if (node->logMask & i) { 316 (void)(*node->write)(log_id, &ts, vec, nr); 317 } 318 } 319 320 return ret; 321 } 322 323 static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) 324 { 325 __android_log_lock(); 326 327 if (write_to_log == __write_to_log_init) { 328 int ret; 329 330 ret = __write_to_log_initialize(); 331 if (ret < 0) { 332 __android_log_unlock(); 333 if (!list_empty(&__android_log_persist_write)) { 334 __write_to_log_daemon(log_id, vec, nr); 335 } 336 return ret; 337 } 338 339 write_to_log = __write_to_log_daemon; 340 } 341 342 __android_log_unlock(); 343 344 return write_to_log(log_id, vec, nr); 345 } 346 347 LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag, 348 const char *msg) 349 { 350 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg); 351 } 352 353 LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio, 354 const char *tag, const char *msg) 355 { 356 struct iovec vec[3]; 357 char tmp_tag[32]; 358 359 if (!tag) 360 tag = ""; 361 362 /* XXX: This needs to go! */ 363 if ((bufID != LOG_ID_RADIO) && 364 (!strcmp(tag, "HTC_RIL") || 365 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */ 366 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */ 367 !strcmp(tag, "AT") || 368 !strcmp(tag, "GSM") || 369 !strcmp(tag, "STK") || 370 !strcmp(tag, "CDMA") || 371 !strcmp(tag, "PHONE") || 372 !strcmp(tag, "SMS"))) { 373 bufID = LOG_ID_RADIO; 374 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */ 375 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag); 376 tag = tmp_tag; 377 } 378 379 #if __BIONIC__ 380 if (prio == ANDROID_LOG_FATAL) { 381 android_set_abort_message(msg); 382 } 383 #endif 384 385 vec[0].iov_base = (unsigned char *)&prio; 386 vec[0].iov_len = 1; 387 vec[1].iov_base = (void *)tag; 388 vec[1].iov_len = strlen(tag) + 1; 389 vec[2].iov_base = (void *)msg; 390 vec[2].iov_len = strlen(msg) + 1; 391 392 return write_to_log(bufID, vec, 3); 393 } 394 395 LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag, 396 const char *fmt, va_list ap) 397 { 398 char buf[LOG_BUF_SIZE]; 399 400 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 401 402 return __android_log_write(prio, tag, buf); 403 } 404 405 LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag, 406 const char *fmt, ...) 407 { 408 va_list ap; 409 char buf[LOG_BUF_SIZE]; 410 411 va_start(ap, fmt); 412 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 413 va_end(ap); 414 415 return __android_log_write(prio, tag, buf); 416 } 417 418 LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio, 419 const char *tag, 420 const char *fmt, ...) 421 { 422 va_list ap; 423 char buf[LOG_BUF_SIZE]; 424 425 va_start(ap, fmt); 426 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 427 va_end(ap); 428 429 return __android_log_buf_write(bufID, prio, tag, buf); 430 } 431 432 LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag, 433 const char *fmt, ...) 434 { 435 char buf[LOG_BUF_SIZE]; 436 437 if (fmt) { 438 va_list ap; 439 va_start(ap, fmt); 440 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); 441 va_end(ap); 442 } else { 443 /* Msg not provided, log condition. N.B. Do not use cond directly as 444 * format string as it could contain spurious '%' syntax (e.g. 445 * "%d" in "blocks%devs == 0"). 446 */ 447 if (cond) 448 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond); 449 else 450 strcpy(buf, "Unspecified assertion failed"); 451 } 452 453 __android_log_write(ANDROID_LOG_FATAL, tag, buf); 454 abort(); /* abort so we have a chance to debug the situation */ 455 /* NOTREACHED */ 456 } 457 458 LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, 459 const void *payload, size_t len) 460 { 461 struct iovec vec[2]; 462 463 vec[0].iov_base = &tag; 464 vec[0].iov_len = sizeof(tag); 465 vec[1].iov_base = (void*)payload; 466 vec[1].iov_len = len; 467 468 return write_to_log(LOG_ID_EVENTS, vec, 2); 469 } 470 471 LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag, 472 const void *payload, 473 size_t len) 474 { 475 struct iovec vec[2]; 476 477 vec[0].iov_base = &tag; 478 vec[0].iov_len = sizeof(tag); 479 vec[1].iov_base = (void*)payload; 480 vec[1].iov_len = len; 481 482 return write_to_log(LOG_ID_SECURITY, vec, 2); 483 } 484 485 /* 486 * Like __android_log_bwrite, but takes the type as well. Doesn't work 487 * for the general case where we're generating lists of stuff, but very 488 * handy if we just want to dump an integer into the log. 489 */ 490 LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type, 491 const void *payload, size_t len) 492 { 493 struct iovec vec[3]; 494 495 vec[0].iov_base = &tag; 496 vec[0].iov_len = sizeof(tag); 497 vec[1].iov_base = &type; 498 vec[1].iov_len = sizeof(type); 499 vec[2].iov_base = (void*)payload; 500 vec[2].iov_len = len; 501 502 return write_to_log(LOG_ID_EVENTS, vec, 3); 503 } 504 505 /* 506 * Like __android_log_bwrite, but used for writing strings to the 507 * event log. 508 */ 509 LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload) 510 { 511 struct iovec vec[4]; 512 char type = EVENT_TYPE_STRING; 513 uint32_t len = strlen(payload); 514 515 vec[0].iov_base = &tag; 516 vec[0].iov_len = sizeof(tag); 517 vec[1].iov_base = &type; 518 vec[1].iov_len = sizeof(type); 519 vec[2].iov_base = &len; 520 vec[2].iov_len = sizeof(len); 521 vec[3].iov_base = (void*)payload; 522 vec[3].iov_len = len; 523 524 return write_to_log(LOG_ID_EVENTS, vec, 4); 525 } 526 527 /* 528 * Like __android_log_security_bwrite, but used for writing strings to the 529 * security log. 530 */ 531 LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag, 532 const char *payload) 533 { 534 struct iovec vec[4]; 535 char type = EVENT_TYPE_STRING; 536 uint32_t len = strlen(payload); 537 538 vec[0].iov_base = &tag; 539 vec[0].iov_len = sizeof(tag); 540 vec[1].iov_base = &type; 541 vec[1].iov_len = sizeof(type); 542 vec[2].iov_base = &len; 543 vec[2].iov_len = sizeof(len); 544 vec[3].iov_base = (void*)payload; 545 vec[3].iov_len = len; 546 547 return write_to_log(LOG_ID_SECURITY, vec, 4); 548 } 549