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 #define DEBUG false 17 #include "Log.h" 18 19 #include "IncidentService.h" 20 21 #include "FdBuffer.h" 22 #include "PrivacyFilter.h" 23 #include "Reporter.h" 24 #include "incidentd_util.h" 25 #include "section_list.h" 26 27 #include <android/os/IncidentReportArgs.h> 28 #include <binder/IPCThreadState.h> 29 #include <binder/IResultReceiver.h> 30 #include <binder/IServiceManager.h> 31 #include <binder/IShellCallback.h> 32 #include <log/log.h> 33 #include <private/android_filesystem_config.h> 34 #include <utils/Looper.h> 35 #include <thread> 36 37 #include <unistd.h> 38 39 enum { 40 WHAT_TAKE_REPORT = 1, 41 WHAT_SEND_BROADCASTS = 2 42 }; 43 44 #define DEFAULT_DELAY_NS (1000000000LL) 45 46 #define DEFAULT_BYTES_SIZE_LIMIT (96 * 1024 * 1024) // 96MB 47 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day 48 49 // Skip these sections for dumpstate only. Dumpstate allows 10s max for each service to dump. 50 // Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report. 51 // Skip 3018 because it takes too long. 52 #define SKIPPED_SECTIONS { 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \ 53 1200, 1201, 1202, /* Native, hal, java traces */ \ 54 3018 /* "meminfo -a --proto" */ } 55 56 namespace android { 57 namespace os { 58 namespace incidentd { 59 60 String16 const APPROVE_INCIDENT_REPORTS("android.permission.APPROVE_INCIDENT_REPORTS"); 61 String16 const DUMP_PERMISSION("android.permission.DUMP"); 62 String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS"); 63 64 static Status checkIncidentPermissions(const IncidentReportArgs& args) { 65 uid_t callingUid = IPCThreadState::self()->getCallingUid(); 66 pid_t callingPid = IPCThreadState::self()->getCallingPid(); 67 if (callingUid == AID_ROOT || callingUid == AID_SHELL) { 68 // Root and shell are ok. 69 return Status::ok(); 70 } 71 72 if (checkCallingPermission(APPROVE_INCIDENT_REPORTS)) { 73 // Permission controller (this is a singleton permission that is always granted 74 // exactly for PermissionController) is allowed to access incident reports 75 // so it can show the user info about what they are approving. 76 return Status::ok(); 77 } 78 79 // checking calling permission. 80 if (!checkCallingPermission(DUMP_PERMISSION)) { 81 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP", 82 callingPid, callingUid); 83 return Status::fromExceptionCode( 84 Status::EX_SECURITY, 85 "Calling process does not have permission: android.permission.DUMP"); 86 } 87 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) { 88 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS", 89 callingPid, callingUid); 90 return Status::fromExceptionCode( 91 Status::EX_SECURITY, 92 "Calling process does not have permission: android.permission.USAGE_STATS"); 93 } 94 95 // checking calling request uid permission. 96 switch (args.getPrivacyPolicy()) { 97 case PRIVACY_POLICY_LOCAL: 98 if (callingUid != AID_SHELL && callingUid != AID_ROOT) { 99 ALOGW("Calling pid %d and uid %d does not have permission to get local data.", 100 callingPid, callingUid); 101 return Status::fromExceptionCode( 102 Status::EX_SECURITY, 103 "Calling process does not have permission to get local data."); 104 } 105 break; 106 case PRIVACY_POLICY_EXPLICIT: 107 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD && 108 callingUid != AID_SYSTEM) { 109 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.", 110 callingPid, callingUid); 111 return Status::fromExceptionCode( 112 Status::EX_SECURITY, 113 "Calling process does not have permission to get explicit data."); 114 } 115 break; 116 } 117 return Status::ok(); 118 } 119 120 static string build_uri(const string& pkg, const string& cls, const string& id) { 121 return "content://android.os.IncidentManager/pending?pkg=" 122 + pkg + "&receiver=" + cls + "&r=" + id; 123 } 124 125 // ================================================================================ 126 ReportHandler::ReportHandler(const sp<WorkDirectory>& workDirectory, 127 const sp<Broadcaster>& broadcaster, const sp<Looper>& handlerLooper, 128 const sp<Throttler>& throttler) 129 :mLock(), 130 mWorkDirectory(workDirectory), 131 mBroadcaster(broadcaster), 132 mHandlerLooper(handlerLooper), 133 mBacklogDelay(DEFAULT_DELAY_NS), 134 mThrottler(throttler), 135 mBatch(new ReportBatch()) { 136 } 137 138 ReportHandler::~ReportHandler() { 139 } 140 141 void ReportHandler::handleMessage(const Message& message) { 142 switch (message.what) { 143 case WHAT_TAKE_REPORT: 144 take_report(); 145 break; 146 case WHAT_SEND_BROADCASTS: 147 send_broadcasts(); 148 break; 149 } 150 } 151 152 void ReportHandler::schedulePersistedReport(const IncidentReportArgs& args) { 153 mBatch->addPersistedReport(args); 154 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT); 155 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT)); 156 } 157 158 void ReportHandler::scheduleStreamingReport(const IncidentReportArgs& args, 159 const sp<IIncidentReportStatusListener>& listener, int streamFd) { 160 mBatch->addStreamingReport(args, listener, streamFd); 161 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT); 162 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT)); 163 } 164 165 void ReportHandler::scheduleSendBacklog() { 166 unique_lock<mutex> lock(mLock); 167 mBacklogDelay = DEFAULT_DELAY_NS; 168 schedule_send_broadcasts_locked(); 169 } 170 171 void ReportHandler::schedule_send_broadcasts_locked() { 172 mHandlerLooper->removeMessages(this, WHAT_SEND_BROADCASTS); 173 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BROADCASTS)); 174 } 175 176 void ReportHandler::take_report() { 177 // Cycle the batch and throttle. 178 sp<ReportBatch> batch; 179 { 180 unique_lock<mutex> lock(mLock); 181 batch = mThrottler->filterBatch(mBatch); 182 } 183 184 if (batch->empty()) { 185 // Nothing to do. 186 return; 187 } 188 189 sp<Reporter> reporter = new Reporter(mWorkDirectory, batch); 190 191 // Take the report, which might take a while. More requests might queue 192 // up while we're doing this, and we'll handle them in their next batch. 193 // TODO: We should further rate-limit the reports to no more than N per time-period. 194 // TODO: Move this inside reporter. 195 size_t reportByteSize = 0; 196 reporter->runReport(&reportByteSize); 197 198 // Tell the throttler how big it was, for the next throttling. 199 // TODO: This still isn't ideal. The throttler really should just track the 200 // persisted reqeusts, but changing Reporter::runReport() to track that individually 201 // will be a big change. 202 if (batch->hasPersistedReports()) { 203 mThrottler->addReportSize(reportByteSize); 204 } 205 206 // Kick off the next steps, one of which is to send any new or otherwise remaining 207 // approvals, and one of which is to send any new or remaining broadcasts. 208 { 209 unique_lock<mutex> lock(mLock); 210 schedule_send_broadcasts_locked(); 211 } 212 } 213 214 void ReportHandler::send_broadcasts() { 215 Broadcaster::broadcast_status_t result = mBroadcaster->sendBroadcasts(); 216 if (result == Broadcaster::BROADCASTS_FINISHED) { 217 // We're done. 218 unique_lock<mutex> lock(mLock); 219 mBacklogDelay = DEFAULT_DELAY_NS; 220 } else if (result == Broadcaster::BROADCASTS_REPEAT) { 221 // It worked, but there are more. 222 unique_lock<mutex> lock(mLock); 223 mBacklogDelay = DEFAULT_DELAY_NS; 224 schedule_send_broadcasts_locked(); 225 } else if (result == Broadcaster::BROADCASTS_BACKOFF) { 226 // There was a failure. Exponential backoff. 227 unique_lock<mutex> lock(mLock); 228 mBacklogDelay *= 2; 229 ALOGI("Error sending to dropbox. Trying again in %lld minutes", 230 (mBacklogDelay / (1000000000LL * 60))); 231 schedule_send_broadcasts_locked(); 232 } 233 } 234 235 // ================================================================================ 236 IncidentService::IncidentService(const sp<Looper>& handlerLooper) { 237 mThrottler = new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS); 238 mWorkDirectory = new WorkDirectory(); 239 mBroadcaster = new Broadcaster(mWorkDirectory); 240 mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper, 241 mThrottler); 242 mBroadcaster->setHandler(mHandler); 243 } 244 245 IncidentService::~IncidentService() {} 246 247 Status IncidentService::reportIncident(const IncidentReportArgs& args) { 248 IncidentReportArgs argsCopy(args); 249 250 // Validate that the privacy policy is one of the real ones. 251 // If it isn't, clamp it to the next more restrictive real one. 252 argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy())); 253 254 // TODO: Check that the broadcast recevier has the proper permissions 255 // TODO: Maybe we should consider relaxing the permissions if it's going to 256 // dropbox, but definitely not if it's going to the broadcaster. 257 Status status = checkIncidentPermissions(args); 258 if (!status.isOk()) { 259 return status; 260 } 261 262 // If they asked for the LOCAL privacy policy, give them EXPLICT. LOCAL has to 263 // be streamed. (This only applies to shell/root, because everyone else would have 264 // been rejected by checkIncidentPermissions()). 265 if (argsCopy.getPrivacyPolicy() < PRIVACY_POLICY_EXPLICIT) { 266 ALOGI("Demoting privacy policy to EXPLICT for persisted report."); 267 argsCopy.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT); 268 } 269 270 // If they didn't specify a component, use dropbox. 271 if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) { 272 argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName()); 273 argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName()); 274 } 275 276 mHandler->schedulePersistedReport(argsCopy); 277 278 return Status::ok(); 279 } 280 281 Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args, 282 const sp<IIncidentReportStatusListener>& listener, 283 const unique_fd& stream) { 284 IncidentReportArgs argsCopy(args); 285 286 // Streaming reports can not also be broadcast. 287 argsCopy.setReceiverPkg(""); 288 argsCopy.setReceiverCls(""); 289 290 // Validate that the privacy policy is one of the real ones. 291 // If it isn't, clamp it to the next more restrictive real one. 292 argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy())); 293 294 Status status = checkIncidentPermissions(argsCopy); 295 if (!status.isOk()) { 296 return status; 297 } 298 299 // The ReportRequest takes ownership of the fd, so we need to dup it. 300 int fd = dup(stream.get()); 301 if (fd < 0) { 302 return Status::fromStatusT(-errno); 303 } 304 305 mHandler->scheduleStreamingReport(argsCopy, listener, fd); 306 307 return Status::ok(); 308 } 309 310 Status IncidentService::systemRunning() { 311 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) { 312 return Status::fromExceptionCode(Status::EX_SECURITY, 313 "Only system uid can call systemRunning"); 314 } 315 316 // When system_server is up and running, schedule the dropbox task to run. 317 mBroadcaster->reset(); 318 mHandler->scheduleSendBacklog(); 319 320 return Status::ok(); 321 } 322 323 Status IncidentService::getIncidentReportList(const String16& pkg16, const String16& cls16, 324 vector<String16>* result) { 325 status_t err; 326 const string pkg(String8(pkg16).string()); 327 const string cls(String8(cls16).string()); 328 329 // List the reports 330 vector<sp<ReportFile>> all; 331 err = mWorkDirectory->getReports(&all, 0); 332 if (err != NO_ERROR) { 333 return Status::fromStatusT(err); 334 } 335 336 // Find the ones that match pkg and cls. 337 for (sp<ReportFile>& file: all) { 338 err = file->loadEnvelope(); 339 if (err != NO_ERROR) { 340 continue; 341 } 342 const ReportFileProto& envelope = file->getEnvelope(); 343 size_t reportCount = envelope.report_size(); 344 for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) { 345 const ReportFileProto_Report& report = envelope.report(reportIndex); 346 if (pkg == report.pkg() && cls == report.cls()) { 347 result->push_back(String16(build_uri(pkg, cls, file->getId()).c_str())); 348 break; 349 } 350 } 351 } 352 353 return Status::ok(); 354 } 355 356 Status IncidentService::getIncidentReport(const String16& pkg16, const String16& cls16, 357 const String16& id16, IncidentManager::IncidentReport* result) { 358 status_t err; 359 360 const string pkg(String8(pkg16).string()); 361 const string cls(String8(cls16).string()); 362 const string id(String8(id16).string()); 363 364 IncidentReportArgs args; 365 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, &args); 366 if (file != nullptr) { 367 // Create pipe 368 int fds[2]; 369 if (pipe(fds) != 0) { 370 ALOGW("Error opening pipe to filter incident report: %s", 371 file->getDataFileName().c_str()); 372 return Status::ok(); 373 } 374 result->setTimestampNs(file->getTimestampNs()); 375 result->setPrivacyPolicy(file->getEnvelope().privacy_policy()); 376 result->takeFileDescriptor(fds[0]); 377 int writeFd = fds[1]; 378 // spawn a thread to write the data. Release the writeFd ownership to the thread. 379 thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); }); 380 381 th.detach(); 382 } 383 384 return Status::ok(); 385 } 386 387 Status IncidentService::deleteIncidentReports(const String16& pkg16, const String16& cls16, 388 const String16& id16) { 389 const string pkg(String8(pkg16).string()); 390 const string cls(String8(cls16).string()); 391 const string id(String8(id16).string()); 392 393 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, nullptr); 394 if (file != nullptr) { 395 mWorkDirectory->commit(file, pkg, cls); 396 } 397 mBroadcaster->clearBroadcasts(pkg, cls, id); 398 399 return Status::ok(); 400 } 401 402 Status IncidentService::deleteAllIncidentReports(const String16& pkg16) { 403 const string pkg(String8(pkg16).string()); 404 405 mWorkDirectory->commitAll(pkg); 406 mBroadcaster->clearPackageBroadcasts(pkg); 407 408 return Status::ok(); 409 } 410 411 /** 412 * Implement our own because the default binder implementation isn't 413 * properly handling SHELL_COMMAND_TRANSACTION. 414 */ 415 status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, 416 uint32_t flags) { 417 status_t err; 418 419 switch (code) { 420 case SHELL_COMMAND_TRANSACTION: { 421 int in = data.readFileDescriptor(); 422 int out = data.readFileDescriptor(); 423 int err = data.readFileDescriptor(); 424 int argc = data.readInt32(); 425 Vector<String8> args; 426 for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 427 args.add(String8(data.readString16())); 428 } 429 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder()); 430 sp<IResultReceiver> resultReceiver = 431 IResultReceiver::asInterface(data.readStrongBinder()); 432 433 FILE* fin = fdopen(in, "r"); 434 FILE* fout = fdopen(out, "w"); 435 FILE* ferr = fdopen(err, "w"); 436 437 if (fin == NULL || fout == NULL || ferr == NULL) { 438 resultReceiver->send(NO_MEMORY); 439 } else { 440 err = command(fin, fout, ferr, args); 441 resultReceiver->send(err); 442 } 443 444 if (fin != NULL) { 445 fflush(fin); 446 fclose(fin); 447 } 448 if (fout != NULL) { 449 fflush(fout); 450 fclose(fout); 451 } 452 if (fout != NULL) { 453 fflush(ferr); 454 fclose(ferr); 455 } 456 457 return NO_ERROR; 458 } break; 459 default: { return BnIncidentManager::onTransact(code, data, reply, flags); } 460 } 461 } 462 463 status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { 464 const int argCount = args.size(); 465 466 if (argCount >= 1) { 467 if (!args[0].compare(String8("privacy"))) { 468 return cmd_privacy(in, out, err, args); 469 } 470 if (!args[0].compare(String8("throttler"))) { 471 mThrottler->dump(out); 472 return NO_ERROR; 473 } 474 if (!args[0].compare(String8("section"))) { 475 int id = atoi(args[1]); 476 int idx = 0; 477 while (SECTION_LIST[idx] != NULL) { 478 const Section* section = SECTION_LIST[idx]; 479 if (section->id == id) { 480 fprintf(out, "Section[%d] %s\n", id, section->name.string()); 481 break; 482 } 483 idx++; 484 } 485 return NO_ERROR; 486 } 487 } 488 return cmd_help(out); 489 } 490 491 status_t IncidentService::cmd_help(FILE* out) { 492 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n"); 493 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n"); 494 fprintf(out, " Prints/parses for the section id.\n\n"); 495 fprintf(out, "usage: adb shell cmd incident section <section_id>\n"); 496 fprintf(out, " Prints section id and its name.\n\n"); 497 fprintf(out, "usage: adb shell cmd incident throttler\n"); 498 fprintf(out, " Prints the current throttler state\n"); 499 return NO_ERROR; 500 } 501 502 static void printPrivacy(const Privacy* p, FILE* out, String8 indent) { 503 if (p == NULL) return; 504 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->policy); 505 if (p->children == NULL) return; 506 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated. 507 printPrivacy(p->children[i], out, indent + " "); 508 } 509 } 510 511 status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { 512 (void)in; 513 514 const int argCount = args.size(); 515 if (argCount >= 3) { 516 String8 opt = args[1]; 517 int sectionId = atoi(args[2].string()); 518 519 const Privacy* p = get_privacy_of_section(sectionId); 520 if (p == NULL) { 521 fprintf(err, "Can't find section id %d\n", sectionId); 522 return NO_ERROR; 523 } 524 fprintf(err, "Get privacy for %d\n", sectionId); 525 if (opt == "print") { 526 printPrivacy(p, out, String8("")); 527 } else if (opt == "parse") { 528 /* 529 FdBuffer buf; 530 status_t error = buf.read(fileno(in), 60000); 531 if (error != NO_ERROR) { 532 fprintf(err, "Error reading from stdin\n"); 533 return error; 534 } 535 fprintf(err, "Read %zu bytes\n", buf.size()); 536 PrivacyFilter pBuf(p, buf.data()); 537 538 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1); 539 error = pBuf.strip(spec); 540 if (error != NO_ERROR) { 541 fprintf(err, "Error strip pii fields with spec %d\n", spec.policy); 542 return error; 543 } 544 return pBuf.flush(fileno(out)); 545 */ 546 return -1; 547 } 548 } else { 549 return cmd_help(out); 550 } 551 return NO_ERROR; 552 } 553 554 status_t IncidentService::dump(int fd, const Vector<String16>& args) { 555 if (std::find(args.begin(), args.end(), String16("--proto")) == args.end()) { 556 ALOGD("Skip dumping incident. Only proto format is supported."); 557 dprintf(fd, "Incident dump only supports proto version.\n"); 558 return NO_ERROR; 559 } 560 561 ALOGD("Dump incident proto"); 562 IncidentReportArgs incidentArgs; 563 incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT); 564 int skipped[] = SKIPPED_SECTIONS; 565 for (const Section** section = SECTION_LIST; *section; section++) { 566 const int id = (*section)->id; 567 if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped) 568 && !section_requires_specific_mention(id)) { 569 incidentArgs.addSection(id); 570 } 571 } 572 573 if (!checkIncidentPermissions(incidentArgs).isOk()) { 574 return PERMISSION_DENIED; 575 } 576 577 // The ReportRequest takes ownership of the fd, so we need to dup it. 578 int fd1 = dup(fd); 579 if (fd1 < 0) { 580 return -errno; 581 } 582 583 // TODO: Remove this. Someone even dumpstate, wanting to get an incident report 584 // should use the API. That will take making dumpstated call the API, which is a 585 // good thing. It also means it won't be subject to the timeout. 586 mHandler->scheduleStreamingReport(incidentArgs, NULL, fd1); 587 588 return NO_ERROR; 589 } 590 591 } // namespace incidentd 592 } // namespace os 593 } // namespace android 594