1 /* 2 * Copyright (C) 2017 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 <ctype.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <inttypes.h> 21 #include <pthread.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <sys/mman.h> 25 #include <sys/stat.h> 26 #include <sys/types.h> 27 #include <unistd.h> 28 29 #include <string> 30 31 #include <android-base/file.h> 32 #include <android-base/macros.h> 33 #include <android-base/stringprintf.h> 34 #include <log/log_event_list.h> 35 #include <log/log_properties.h> 36 #include <private/android_filesystem_config.h> 37 38 #include "LogTags.h" 39 #include "LogUtils.h" 40 41 static LogTags* logtags; 42 43 const char LogTags::system_event_log_tags[] = "/system/etc/event-log-tags"; 44 const char LogTags::dynamic_event_log_tags[] = "/dev/event-log-tags"; 45 // Only for debug 46 const char LogTags::debug_event_log_tags[] = "/data/misc/logd/event-log-tags"; 47 48 // Sniff for first uid=%d in utf8z comment string 49 static uid_t sniffUid(const char* comment, const char* endp) { 50 if (!comment) return AID_ROOT; 51 52 if (*comment == '#') ++comment; 53 while ((comment < endp) && (*comment != '\n') && isspace(*comment)) 54 ++comment; 55 static const char uid_str[] = "uid="; 56 if (((comment + strlen(uid_str)) >= endp) || 57 fastcmp<strncmp>(comment, uid_str, strlen(uid_str)) || 58 !isdigit(comment[strlen(uid_str)])) 59 return AID_ROOT; 60 char* cp; 61 unsigned long Uid = strtoul(comment + 4, &cp, 10); 62 if ((cp > endp) || (Uid >= INT_MAX)) return AID_ROOT; 63 64 return Uid; 65 } 66 67 // Checks for file corruption, and report false if there was no need 68 // to rebuild the referenced file. Failure to rebuild is only logged, 69 // does not cause a return value of false. 70 bool LogTags::RebuildFileEventLogTags(const char* filename, bool warn) { 71 int fd; 72 73 { 74 android::RWLock::AutoRLock readLock(rwlock); 75 76 if (tag2total.begin() == tag2total.end()) { 77 return false; 78 } 79 80 file2watermark_const_iterator iwater = file2watermark.find(filename); 81 if (iwater == file2watermark.end()) { 82 return false; 83 } 84 85 struct stat sb; 86 if (!stat(filename, &sb) && ((size_t)sb.st_size >= iwater->second)) { 87 return false; 88 } 89 90 // dump what we already know back into the file? 91 fd = TEMP_FAILURE_RETRY(open( 92 filename, O_WRONLY | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY)); 93 if (fd >= 0) { 94 time_t now = time(NULL); 95 struct tm tm; 96 localtime_r(&now, &tm); 97 char timebuf[20]; 98 size_t len = 99 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", &tm); 100 android::base::WriteStringToFd( 101 android::base::StringPrintf( 102 "# Rebuilt %.20s, content owned by logd\n", timebuf), 103 fd); 104 for (const auto& it : tag2total) { 105 android::base::WriteStringToFd( 106 formatEntry_locked(it.first, AID_ROOT), fd); 107 } 108 close(fd); 109 } 110 } 111 112 if (warn) { 113 android::prdebug( 114 ((fd < 0) ? "%s failed to rebuild" 115 : "%s missing, damaged or truncated; rebuilt"), 116 filename); 117 } 118 119 if (fd >= 0) { 120 android::RWLock::AutoWLock writeLock(rwlock); 121 122 struct stat sb; 123 if (!stat(filename, &sb)) file2watermark[filename] = sb.st_size; 124 } 125 126 return true; 127 } 128 129 void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name, 130 const std::string& Format, const char* source, 131 bool warn) { 132 std::string Key = Name; 133 if (Format.length()) Key += "+" + Format; 134 135 bool update = !source || !!strcmp(source, system_event_log_tags); 136 bool newOne; 137 138 { 139 android::RWLock::AutoWLock writeLock(rwlock); 140 141 tag2total_const_iterator itot = tag2total.find(tag); 142 143 // unlikely except for dupes, or updates to uid list (more later) 144 if (itot != tag2total.end()) update = false; 145 146 newOne = tag2name.find(tag) == tag2name.end(); 147 key2tag[Key] = tag; 148 149 if (Format.length()) { 150 if (key2tag.find(Name) == key2tag.end()) { 151 key2tag[Name] = tag; 152 } 153 tag2format[tag] = Format; 154 } 155 tag2name[tag] = Name; 156 157 tag2uid_const_iterator ut = tag2uid.find(tag); 158 if (ut != tag2uid.end()) { 159 if (uid == AID_ROOT) { 160 tag2uid.erase(ut); 161 update = true; 162 } else if (ut->second.find(uid) == ut->second.end()) { 163 const_cast<uid_list&>(ut->second).emplace(uid); 164 update = true; 165 } 166 } else if (newOne && (uid != AID_ROOT)) { 167 tag2uid[tag].emplace(uid); 168 update = true; 169 } 170 171 // updatePersist -> trigger output on modified 172 // content, reset tag2total if available 173 if (update && (itot != tag2total.end())) tag2total[tag] = 0; 174 } 175 176 if (update) { 177 WritePersistEventLogTags(tag, uid, source); 178 } else if (warn && !newOne && source) { 179 // For the files, we want to report dupes. 180 android::prdebug("Multiple tag %" PRIu32 " %s %s %s", tag, Name.c_str(), 181 Format.c_str(), source); 182 } 183 } 184 185 // Read the event log tags file, and build up our internal database 186 void LogTags::ReadFileEventLogTags(const char* filename, bool warn) { 187 bool etc = !strcmp(filename, system_event_log_tags); 188 bool debug = !etc && !strcmp(filename, debug_event_log_tags); 189 190 if (!etc) { 191 RebuildFileEventLogTags(filename, warn); 192 } 193 std::string content; 194 if (android::base::ReadFileToString(filename, &content)) { 195 char* cp = (char*)content.c_str(); 196 char* endp = cp + content.length(); 197 198 { 199 android::RWLock::AutoRLock writeLock(rwlock); 200 201 file2watermark[filename] = content.length(); 202 } 203 204 char* lineStart = cp; 205 while (cp < endp) { 206 if (*cp == '\n') { 207 lineStart = cp; 208 } else if (lineStart) { 209 if (*cp == '#') { 210 /* comment; just scan to end */ 211 lineStart = NULL; 212 } else if (isdigit(*cp)) { 213 unsigned long Tag = strtoul(cp, &cp, 10); 214 if (warn && (Tag > emptyTag)) { 215 android::prdebug("tag too large %lu", Tag); 216 } 217 while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp; 218 if (cp >= endp) break; 219 if (*cp == '\n') continue; 220 const char* name = cp; 221 /* Determine whether it is a valid tag name [a-zA-Z0-9_] */ 222 bool hasAlpha = false; 223 while ((cp < endp) && (isalnum(*cp) || (*cp == '_'))) { 224 if (!isdigit(*cp)) hasAlpha = true; 225 ++cp; 226 } 227 std::string Name(name, cp - name); 228 #ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT 229 static const size_t maximum_official_tag_name_size = 24; 230 if (warn && 231 (Name.length() > maximum_official_tag_name_size)) { 232 android::prdebug("tag name too long %s", Name.c_str()); 233 } 234 #endif 235 if (hasAlpha && 236 ((cp >= endp) || (*cp == '#') || isspace(*cp))) { 237 if (Tag > emptyTag) { 238 if (*cp != '\n') lineStart = NULL; 239 continue; 240 } 241 while ((cp < endp) && (*cp != '\n') && isspace(*cp)) 242 ++cp; 243 const char* format = cp; 244 uid_t uid = AID_ROOT; 245 while ((cp < endp) && (*cp != '\n')) { 246 if (*cp == '#') { 247 uid = sniffUid(cp, endp); 248 lineStart = NULL; 249 break; 250 } 251 ++cp; 252 } 253 while ((cp > format) && isspace(cp[-1])) { 254 --cp; 255 lineStart = NULL; 256 } 257 std::string Format(format, cp - format); 258 259 AddEventLogTags((uint32_t)Tag, uid, Name, Format, 260 filename, warn); 261 } else { 262 if (warn) { 263 android::prdebug("tag name invalid %.*s", 264 (int)(cp - name + 1), name); 265 } 266 lineStart = NULL; 267 } 268 } else if (!isspace(*cp)) { 269 break; 270 } 271 } 272 cp++; 273 } 274 } else if (warn) { 275 android::prdebug("Cannot read %s", filename); 276 } 277 } 278 279 // Extract a 4-byte value from a byte stream. 280 static inline uint32_t get4LE(const char* msg) { 281 const uint8_t* src = reinterpret_cast<const uint8_t*>(msg); 282 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 283 } 284 285 // Additional persistent sources for invented log tags. Read the 286 // special pmsg event for log tags, and build up our internal 287 // database with any found. 288 void LogTags::ReadPersistEventLogTags() { 289 struct logger_list* logger_list = android_logger_list_alloc( 290 ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, 0, 291 (pid_t)0); 292 if (!logger_list) return; 293 294 struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS); 295 struct logger* s = android_logger_open(logger_list, LOG_ID_SECURITY); 296 if (!e && !s) { 297 android_logger_list_free(logger_list); 298 return; 299 } 300 301 for (;;) { 302 struct log_msg log_msg; 303 int ret = android_logger_list_read(logger_list, &log_msg); 304 if (ret <= 0) break; 305 306 const char* msg = log_msg.msg(); 307 if (!msg) continue; 308 if (log_msg.entry.len <= sizeof(uint32_t)) continue; 309 uint32_t Tag = get4LE(msg); 310 if (Tag != TAG_DEF_LOG_TAG) continue; 311 uid_t uid = (log_msg.entry.hdr_size >= sizeof(logger_entry_v4)) 312 ? log_msg.entry.uid 313 : AID_ROOT; 314 315 std::string Name; 316 std::string Format; 317 android_log_list_element elem; 318 { 319 android_log_event_list ctx(log_msg); 320 elem = ctx.read(); 321 if (elem.type != EVENT_TYPE_LIST) { 322 continue; 323 } 324 elem = ctx.read(); 325 if (elem.type != EVENT_TYPE_INT) { 326 continue; 327 } 328 Tag = elem.data.int32; 329 elem = ctx.read(); 330 if (elem.type != EVENT_TYPE_STRING) { 331 continue; 332 } 333 Name = std::string(elem.data.string, elem.len); 334 elem = ctx.read(); 335 if (elem.type != EVENT_TYPE_STRING) { 336 continue; 337 } 338 Format = std::string(elem.data.string, elem.len); 339 elem = ctx.read(); 340 } 341 if ((elem.type != EVENT_TYPE_LIST_STOP) || !elem.complete) continue; 342 343 AddEventLogTags(Tag, uid, Name, Format); 344 } 345 android_logger_list_free(logger_list); 346 } 347 348 LogTags::LogTags() { 349 ReadFileEventLogTags(system_event_log_tags); 350 // Following will likely fail on boot, but is required if logd restarts 351 ReadFileEventLogTags(dynamic_event_log_tags, false); 352 if (__android_log_is_debuggable()) { 353 ReadFileEventLogTags(debug_event_log_tags, false); 354 } 355 ReadPersistEventLogTags(); 356 357 logtags = this; 358 } 359 360 // Converts an event tag into a name 361 const char* LogTags::tagToName(uint32_t tag) const { 362 tag2name_const_iterator it; 363 364 android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); 365 366 it = tag2name.find(tag); 367 if ((it == tag2name.end()) || (it->second.length() == 0)) return NULL; 368 369 return it->second.c_str(); 370 } 371 372 // Prototype in LogUtils.h allowing external access to our database. 373 // 374 // This must be a pure reader to our database, as everything else is 375 // guaranteed single-threaded except this access point which is 376 // asynchonous and can be multithreaded and thus rentrant. The 377 // object's rwlock is only used to guarantee atomic access to the 378 // unordered_map to prevent corruption, with a requirement to be a 379 // low chance of contention for this call. If we end up changing 380 // this algorithm resulting in write, then we should use a different 381 // lock than the object's rwlock to protect groups of associated 382 // actions. 383 const char* android::tagToName(uint32_t tag) { 384 LogTags* me = logtags; 385 386 if (!me) return NULL; 387 me->WritePmsgEventLogTags(tag); 388 return me->tagToName(tag); 389 } 390 391 // Prototype in LogUtils.h allowing external access to our database. 392 // 393 // This only works on userdebug and eng devices to re-read the 394 // /data/misc/logd/event-log-tags file right after /data is mounted. 395 // The operation is near to boot and should only happen once. There 396 // are races associated with its use since it can trigger a Rebuild 397 // of the file, but that is a can-not-happen since the file was not 398 // read yet. More dangerous if called later, but if all is well it 399 // should just skip over everything and not write any new entries. 400 void android::ReReadEventLogTags() { 401 LogTags* me = logtags; 402 403 if (me && __android_log_is_debuggable()) { 404 me->ReadFileEventLogTags(me->debug_event_log_tags); 405 } 406 } 407 408 // converts an event tag into a format 409 const char* LogTags::tagToFormat(uint32_t tag) const { 410 tag2format_const_iterator iform; 411 412 android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); 413 414 iform = tag2format.find(tag); 415 if (iform == tag2format.end()) return NULL; 416 417 return iform->second.c_str(); 418 } 419 420 // converts a name into an event tag 421 uint32_t LogTags::nameToTag(const char* name) const { 422 uint32_t ret = emptyTag; 423 424 // Bug: Only works for a single entry, we can have multiple entries, 425 // one for each format, so we find first entry recorded, or entry with 426 // no format associated with it. 427 428 android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); 429 430 key2tag_const_iterator ik = key2tag.find(std::string(name)); 431 if (ik != key2tag.end()) ret = ik->second; 432 433 return ret; 434 } 435 436 // Caller must perform locks, can be under reader (for pre-check) or 437 // writer lock. We use this call to invent a new deterministically 438 // random tag, unique is cleared if no conflicts. If format is NULL, 439 // we are in readonly mode. 440 uint32_t LogTags::nameToTag_locked(const std::string& name, const char* format, 441 bool& unique) { 442 key2tag_const_iterator ik; 443 444 bool write = format != NULL; 445 unique = write; 446 447 if (!write) { 448 // Bug: Only works for a single entry, we can have multiple entries, 449 // one for each format, so we find first entry recorded, or entry with 450 // no format associated with it. 451 ik = key2tag.find(name); 452 if (ik == key2tag.end()) return emptyTag; 453 return ik->second; 454 } 455 456 std::string Key(name); 457 if (*format) Key += std::string("+") + format; 458 459 ik = key2tag.find(Key); 460 if (ik != key2tag.end()) { 461 unique = false; 462 return ik->second; 463 } 464 465 size_t Hash = key2tag.hash_function()(Key); 466 uint32_t Tag = Hash; 467 // This sets an upper limit on the conflics we are allowed to deal with. 468 for (unsigned i = 0; i < 256;) { 469 tag2name_const_iterator it = tag2name.find(Tag); 470 if (it == tag2name.end()) return Tag; 471 std::string localKey(it->second); 472 tag2format_const_iterator iform = tag2format.find(Tag); 473 if ((iform == tag2format.end()) && iform->second.length()) { 474 localKey += "+" + iform->second; 475 } 476 unique = !!it->second.compare(localKey); 477 if (!unique) return Tag; // unlikely except in a race 478 479 ++i; 480 // Algorithm to convert hash to next tag 481 if (i < 32) { 482 Tag = (Hash >> i); 483 // size_t is 32 bits, or upper word zero, rotate 484 if ((sizeof(Hash) <= 4) || ((Hash & (uint64_t(-1LL) << 32)) == 0)) { 485 Tag |= Hash << (32 - i); 486 } 487 } else { 488 Tag = Hash + i - 31; 489 } 490 } 491 return emptyTag; 492 } 493 494 static int openFile(const char* name, int mode, bool warning) { 495 int fd = TEMP_FAILURE_RETRY(open(name, mode)); 496 if ((fd < 0) && warning) { 497 android::prdebug("Failed open %s (%d)", name, errno); 498 } 499 return fd; 500 } 501 502 void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) { 503 android::RWLock::AutoRLock readLock(rwlock); 504 505 tag2total_const_iterator itot = tag2total.find(tag); 506 if (itot == tag2total.end()) return; // source is a static entry 507 508 size_t lastTotal = itot->second; 509 510 // Every 16K (half the smallest configurable pmsg buffer size) record 511 static const size_t rate_to_pmsg = 16 * 1024; 512 if (lastTotal && ((android::sizesTotal() - lastTotal) < rate_to_pmsg)) { 513 return; 514 } 515 516 static int pmsg_fd = -1; 517 if (pmsg_fd < 0) { 518 pmsg_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); 519 // unlikely, but deal with partners with borken pmsg 520 if (pmsg_fd < 0) return; 521 } 522 523 std::string Name = tag2name[tag]; 524 tag2format_const_iterator iform = tag2format.find(tag); 525 std::string Format = (iform != tag2format.end()) ? iform->second : ""; 526 527 __android_log_event_list ctx(TAG_DEF_LOG_TAG); 528 ctx << tag << Name << Format; 529 std::string buffer(ctx); 530 if (buffer.length() <= 0) return; // unlikely 531 532 /* 533 * struct { 534 * // what we provide to pstore 535 * android_pmsg_log_header_t pmsgHeader; 536 * // what we provide to file 537 * android_log_header_t header; 538 * // caller provides 539 * union { 540 * struct { 541 * char prio; 542 * char payload[]; 543 * } string; 544 * struct { 545 * uint32_t tag 546 * char payload[]; 547 * } binary; 548 * }; 549 * }; 550 */ 551 552 struct timespec ts; 553 clock_gettime(android_log_clockid(), &ts); 554 555 android_log_header_t header = { 556 .id = LOG_ID_EVENTS, 557 .tid = (uint16_t)gettid(), 558 .realtime.tv_sec = (uint32_t)ts.tv_sec, 559 .realtime.tv_nsec = (uint32_t)ts.tv_nsec, 560 }; 561 562 uint32_t outTag = TAG_DEF_LOG_TAG; 563 outTag = get4LE((const char*)&outTag); 564 565 android_pmsg_log_header_t pmsgHeader = { 566 .magic = LOGGER_MAGIC, 567 .len = (uint16_t)(sizeof(pmsgHeader) + sizeof(header) + sizeof(outTag) + 568 buffer.length()), 569 .uid = (uint16_t)AID_ROOT, 570 .pid = (uint16_t)getpid(), 571 }; 572 573 struct iovec Vec[] = { { (unsigned char*)&pmsgHeader, sizeof(pmsgHeader) }, 574 { (unsigned char*)&header, sizeof(header) }, 575 { (unsigned char*)&outTag, sizeof(outTag) }, 576 { (unsigned char*)const_cast<char*>(buffer.data()), 577 buffer.length() } }; 578 579 tag2uid_const_iterator ut = tag2uid.find(tag); 580 if (ut == tag2uid.end()) { 581 TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); 582 } else if (uid != AID_ROOT) { 583 pmsgHeader.uid = (uint16_t)uid; 584 TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); 585 } else { 586 for (auto& it : ut->second) { 587 pmsgHeader.uid = (uint16_t)it; 588 TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); 589 } 590 } 591 } 592 593 void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) { 594 static const int mode = 595 O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY; 596 597 int fd = openFile(dynamic_event_log_tags, mode, true); 598 if (fd < 0) return; 599 600 android::RWLock::AutoWLock writeLock(rwlock); 601 602 std::string ret = formatEntry_locked(tag, uid, false); 603 android::base::WriteStringToFd(ret, fd); 604 close(fd); 605 606 size_t size = 0; 607 file2watermark_const_iterator iwater; 608 609 iwater = file2watermark.find(dynamic_event_log_tags); 610 if (iwater != file2watermark.end()) size = iwater->second; 611 612 file2watermark[dynamic_event_log_tags] = size + ret.length(); 613 } 614 615 void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) { 616 static const int mode = 617 O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY; 618 619 static bool one = true; 620 int fd = openFile(debug_event_log_tags, mode, one); 621 one = fd >= 0; 622 if (!one) return; 623 624 android::RWLock::AutoWLock writeLock(rwlock); 625 626 std::string ret = formatEntry_locked(tag, uid, false); 627 android::base::WriteStringToFd(ret, fd); 628 close(fd); 629 630 size_t size = 0; 631 file2watermark_const_iterator iwater; 632 633 iwater = file2watermark.find(debug_event_log_tags); 634 if (iwater != file2watermark.end()) size = iwater->second; 635 636 file2watermark[debug_event_log_tags] = size + ret.length(); 637 } 638 639 // How we maintain some runtime or reboot stickiness 640 void LogTags::WritePersistEventLogTags(uint32_t tag, uid_t uid, 641 const char* source) { 642 // very unlikely 643 bool etc = source && !strcmp(source, system_event_log_tags); 644 if (etc) return; 645 646 bool dynamic = source && !strcmp(source, dynamic_event_log_tags); 647 bool debug = (!dynamic && source && !strcmp(source, debug_event_log_tags)) || 648 !__android_log_is_debuggable(); 649 650 WritePmsgEventLogTags(tag, uid); 651 652 size_t lastTotal = 0; 653 { 654 android::RWLock::AutoRLock readLock(rwlock); 655 656 tag2total_const_iterator itot = tag2total.find(tag); 657 if (itot != tag2total.end()) lastTotal = itot->second; 658 } 659 660 if (lastTotal == 0) { // denotes first time for this one 661 if (!dynamic || !RebuildFileEventLogTags(dynamic_event_log_tags)) { 662 WriteDynamicEventLogTags(tag, uid); 663 } 664 665 if (!debug && !RebuildFileEventLogTags(debug_event_log_tags)) { 666 WriteDebugEventLogTags(tag, uid); 667 } 668 } 669 670 lastTotal = android::sizesTotal(); 671 if (!lastTotal) ++lastTotal; 672 673 // record totals for next watermark. 674 android::RWLock::AutoWLock writeLock(rwlock); 675 tag2total[tag] = lastTotal; 676 } 677 678 // nameToTag converts a name into an event tag. If format is NULL, then we 679 // are in readonly mode. 680 uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) { 681 std::string Name = std::string(name); 682 bool write = format != NULL; 683 bool updateUid = uid != AID_ROOT; 684 bool updateFormat = format && *format; 685 bool unique; 686 uint32_t Tag; 687 688 { 689 android::RWLock::AutoRLock readLock(rwlock); 690 691 Tag = nameToTag_locked(Name, format, unique); 692 if (updateUid && (Tag != emptyTag) && !unique) { 693 tag2uid_const_iterator ut = tag2uid.find(Tag); 694 if (updateUid) { 695 if ((ut != tag2uid.end()) && 696 (ut->second.find(uid) == ut->second.end())) { 697 unique = write; // write passthrough to update uid counts 698 if (!write) Tag = emptyTag; // deny read access 699 } 700 } else { 701 unique = write && (ut != tag2uid.end()); 702 } 703 } 704 } 705 706 if (Tag == emptyTag) return Tag; 707 WritePmsgEventLogTags(Tag, uid); // record references periodically 708 if (!unique) return Tag; 709 710 bool updateWrite = false; 711 bool updateTag; 712 713 // Special case of AddEventLogTags, checks per-uid counter which makes 714 // no sense there, and is also optimized somewhat to reduce write times. 715 { 716 android::RWLock::AutoWLock writeLock(rwlock); 717 718 // double check after switch from read lock to write lock for Tag 719 updateTag = tag2name.find(Tag) == tag2name.end(); 720 // unlikely, either update, race inviting conflict or multiple uids 721 if (!updateTag) { 722 Tag = nameToTag_locked(Name, format, unique); 723 if (Tag == emptyTag) return Tag; 724 // is it multiple uid's setting this value 725 if (!unique) { 726 tag2uid_const_iterator ut = tag2uid.find(Tag); 727 if (updateUid) { 728 // Add it to the uid list 729 if ((ut == tag2uid.end()) || 730 (ut->second.find(uid) != ut->second.end())) { 731 return Tag; 732 } 733 const_cast<uid_list&>(ut->second).emplace(uid); 734 updateWrite = true; 735 } else { 736 if (ut == tag2uid.end()) return Tag; 737 // (system) adding a global one, erase the uid list 738 tag2uid.erase(ut); 739 updateWrite = true; 740 } 741 } 742 } 743 744 // Update section 745 size_t count; 746 if (updateUid) { 747 count = 0; 748 uid2count_const_iterator ci = uid2count.find(uid); 749 if (ci != uid2count.end()) { 750 count = ci->second; 751 if (count >= max_per_uid) { 752 if (!updateWrite) return emptyTag; 753 // If we are added to the per-Uid perms, leak the Tag 754 // if it already exists. 755 updateUid = false; 756 updateTag = false; 757 updateFormat = false; 758 } 759 } 760 } 761 762 // updateWrite -> trigger output on modified content, reset tag2total 763 // also sets static to dynamic entries if they are alterred, 764 // only occurs if they have a uid, and runtime adds another uid. 765 if (updateWrite) tag2total[Tag] = 0; 766 767 if (updateTag) { 768 // mark as a dynamic entry, but do not upset current total counter 769 tag2total_const_iterator itot = tag2total.find(Tag); 770 if (itot == tag2total.end()) tag2total[Tag] = 0; 771 772 if (*format) { 773 key2tag[Name + "+" + format] = Tag; 774 if (key2tag.find(Name) == key2tag.end()) key2tag[Name] = Tag; 775 } else { 776 key2tag[Name] = Tag; 777 } 778 tag2name[Tag] = Name; 779 } 780 if (updateFormat) tag2format[Tag] = format; 781 782 if (updateUid) { 783 tag2uid[Tag].emplace(uid); 784 uid2count[uid] = count + 1; 785 } 786 } 787 788 if (updateTag || updateFormat || updateWrite) { 789 WritePersistEventLogTags(Tag, uid); 790 } 791 792 return Tag; 793 } 794 795 std::string LogTags::formatEntry(uint32_t tag, uid_t uid, const char* name, 796 const char* format) { 797 if (!format || !format[0]) { 798 return android::base::StringPrintf("%" PRIu32 "\t%s\n", tag, name); 799 } 800 size_t len = (strlen(name) + 7) / 8; 801 static const char tabs[] = "\t\t\t"; 802 if (len > strlen(tabs)) len = strlen(tabs); 803 std::string Uid; 804 if (uid != AID_ROOT) Uid = android::base::StringPrintf(" # uid=%u", uid); 805 return android::base::StringPrintf("%" PRIu32 "\t%s%s\t%s%s\n", tag, name, 806 &tabs[len], format, Uid.c_str()); 807 } 808 809 std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid, 810 bool authenticate) { 811 const char* name = tag2name[tag].c_str(); 812 813 const char* format = ""; 814 tag2format_const_iterator iform = tag2format.find(tag); 815 if (iform != tag2format.end()) format = iform->second.c_str(); 816 817 // Access permission test, do not report dynamic entries 818 // that do not belong to us. 819 tag2uid_const_iterator ut = tag2uid.find(tag); 820 if (ut == tag2uid.end()) { 821 return formatEntry(tag, AID_ROOT, name, format); 822 } 823 if (uid != AID_ROOT) { 824 if (authenticate && (ut->second.find(uid) == ut->second.end())) { 825 return std::string(""); 826 } 827 return formatEntry(tag, uid, name, format); 828 } 829 830 // Show all, one for each registered uid (we are group root) 831 std::string ret; 832 for (auto& it : ut->second) { 833 ret += formatEntry(tag, it, name, format); 834 } 835 return ret; 836 } 837 838 std::string LogTags::formatEntry(uint32_t tag, uid_t uid) { 839 android::RWLock::AutoRLock readLock(rwlock); 840 return formatEntry_locked(tag, uid); 841 } 842 843 std::string LogTags::formatGetEventTag(uid_t uid, const char* name, 844 const char* format) { 845 bool all = name && (name[0] == '*') && !name[1]; 846 bool list = !name || all; 847 std::string ret; 848 849 if (!list) { 850 // switch to read entry only if format == "*" 851 if (format && (format[0] == '*') && !format[1]) format = NULL; 852 853 // WAI: for null format, only works for a single entry, we can have 854 // multiple entries, one for each format, so we find first entry 855 // recorded, or entry with no format associated with it. 856 // We may desire to print all that match the name, but we did not 857 // add a mapping table for that and the cost is too high. 858 uint32_t tag = nameToTag(uid, name, format); 859 if (tag == emptyTag) return std::string("-1 ESRCH"); 860 if (uid == AID_ROOT) { 861 android::RWLock::AutoRLock readLock(rwlock); 862 863 // first uid in list so as to manufacture an accurate reference 864 tag2uid_const_iterator ut = tag2uid.find(tag); 865 if ((ut != tag2uid.end()) && 866 (ut->second.begin() != ut->second.end())) { 867 uid = *(ut->second.begin()); 868 } 869 } 870 ret = formatEntry(tag, uid, name, format ?: tagToFormat(tag)); 871 if (!ret.length()) return std::string("-1 ESRCH"); 872 return ret; 873 } 874 875 android::RWLock::AutoRLock readLock(rwlock); 876 if (all) { 877 // everything under the sun 878 for (const auto& it : tag2name) { 879 ret += formatEntry_locked(it.first, uid); 880 } 881 } else { 882 // set entries are dynamic 883 for (const auto& it : tag2total) { 884 ret += formatEntry_locked(it.first, uid); 885 } 886 } 887 return ret; 888 } 889