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 "PrivacyBuffer.h" 23 #include "Reporter.h" 24 #include "incidentd_util.h" 25 #include "section_list.h" 26 27 #include <binder/IPCThreadState.h> 28 #include <binder/IResultReceiver.h> 29 #include <binder/IServiceManager.h> 30 #include <binder/IShellCallback.h> 31 #include <cutils/log.h> 32 #include <private/android_filesystem_config.h> 33 #include <utils/Looper.h> 34 35 #include <unistd.h> 36 37 enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 }; 38 39 #define DEFAULT_BACKLOG_DELAY_NS (1000000000LL) 40 41 #define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB 42 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day 43 44 namespace android { 45 namespace os { 46 namespace incidentd { 47 48 String16 const DUMP_PERMISSION("android.permission.DUMP"); 49 String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS"); 50 51 static Status checkIncidentPermissions(const IncidentReportArgs& args) { 52 uid_t callingUid = IPCThreadState::self()->getCallingUid(); 53 pid_t callingPid = IPCThreadState::self()->getCallingPid(); 54 if (callingUid == AID_ROOT || callingUid == AID_SHELL) { 55 // root doesn't have permission.DUMP if don't do this! 56 return Status::ok(); 57 } 58 59 // checking calling permission. 60 if (!checkCallingPermission(DUMP_PERMISSION)) { 61 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP", 62 callingPid, callingUid); 63 return Status::fromExceptionCode( 64 Status::EX_SECURITY, 65 "Calling process does not have permission: android.permission.DUMP"); 66 } 67 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) { 68 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS", 69 callingPid, callingUid); 70 return Status::fromExceptionCode( 71 Status::EX_SECURITY, 72 "Calling process does not have permission: android.permission.USAGE_STATS"); 73 } 74 75 // checking calling request uid permission. 76 switch (args.dest()) { 77 case DEST_LOCAL: 78 if (callingUid != AID_SHELL && callingUid != AID_ROOT) { 79 ALOGW("Calling pid %d and uid %d does not have permission to get local data.", 80 callingPid, callingUid); 81 return Status::fromExceptionCode( 82 Status::EX_SECURITY, 83 "Calling process does not have permission to get local data."); 84 } 85 case DEST_EXPLICIT: 86 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD && 87 callingUid != AID_SYSTEM) { 88 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.", 89 callingPid, callingUid); 90 return Status::fromExceptionCode( 91 Status::EX_SECURITY, 92 "Calling process does not have permission to get explicit data."); 93 } 94 } 95 return Status::ok(); 96 } 97 98 // ================================================================================ 99 ReportRequestQueue::ReportRequestQueue() {} 100 101 ReportRequestQueue::~ReportRequestQueue() {} 102 103 void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) { 104 unique_lock<mutex> lock(mLock); 105 mQueue.push_back(request); 106 } 107 108 sp<ReportRequest> ReportRequestQueue::getNextRequest() { 109 unique_lock<mutex> lock(mLock); 110 if (mQueue.empty()) { 111 return NULL; 112 } else { 113 sp<ReportRequest> front(mQueue.front()); 114 mQueue.pop_front(); 115 return front; 116 } 117 } 118 119 // ================================================================================ 120 ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue, 121 const sp<Throttler>& throttler) 122 : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS), 123 mHandlerLooper(handlerLooper), 124 mQueue(queue), 125 mThrottler(throttler) {} 126 127 ReportHandler::~ReportHandler() {} 128 129 void ReportHandler::handleMessage(const Message& message) { 130 switch (message.what) { 131 case WHAT_RUN_REPORT: 132 run_report(); 133 break; 134 case WHAT_SEND_BACKLOG_TO_DROPBOX: 135 send_backlog_to_dropbox(); 136 break; 137 } 138 } 139 140 void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) { 141 mQueue->addRequest(request); 142 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT); 143 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT)); 144 } 145 146 void ReportHandler::scheduleSendBacklogToDropbox() { 147 unique_lock<mutex> lock(mLock); 148 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS; 149 schedule_send_backlog_to_dropbox_locked(); 150 } 151 152 void ReportHandler::schedule_send_backlog_to_dropbox_locked() { 153 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX); 154 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX)); 155 } 156 157 void ReportHandler::run_report() { 158 sp<Reporter> reporter = new Reporter(); 159 160 // Merge all of the requests into one that has all of the 161 // requested fields. 162 while (true) { 163 sp<ReportRequest> request = mQueue->getNextRequest(); 164 if (request == NULL) { 165 break; 166 } 167 reporter->batch.add(request); 168 } 169 170 if (mThrottler->shouldThrottle()) { 171 ALOGW("RunReport got throttled."); 172 return; 173 } 174 175 // Take the report, which might take a while. More requests might queue 176 // up while we're doing this, and we'll handle them in their next batch. 177 // TODO: We should further rate-limit the reports to no more than N per time-period. 178 size_t reportByteSize = 0; 179 Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize); 180 mThrottler->addReportSize(reportByteSize); 181 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) { 182 unique_lock<mutex> lock(mLock); 183 schedule_send_backlog_to_dropbox_locked(); 184 } 185 } 186 187 void ReportHandler::send_backlog_to_dropbox() { 188 if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) { 189 // There was a failure. Exponential backoff. 190 unique_lock<mutex> lock(mLock); 191 mBacklogDelay *= 2; 192 ALOGI("Error sending to dropbox. Trying again in %lld minutes", 193 (mBacklogDelay / (1000000000LL * 60))); 194 schedule_send_backlog_to_dropbox_locked(); 195 } else { 196 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS; 197 } 198 } 199 200 // ================================================================================ 201 IncidentService::IncidentService(const sp<Looper>& handlerLooper) 202 : mQueue(new ReportRequestQueue()), 203 mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) { 204 mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler); 205 } 206 207 IncidentService::~IncidentService() {} 208 209 Status IncidentService::reportIncident(const IncidentReportArgs& args) { 210 ALOGI("reportIncident"); 211 212 Status status = checkIncidentPermissions(args); 213 if (!status.isOk()) { 214 return status; 215 } 216 217 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1)); 218 219 return Status::ok(); 220 } 221 222 Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args, 223 const sp<IIncidentReportStatusListener>& listener, 224 const unique_fd& stream) { 225 ALOGI("reportIncidentToStream"); 226 227 Status status = checkIncidentPermissions(args); 228 if (!status.isOk()) { 229 return status; 230 } 231 232 int fd = dup(stream.get()); 233 if (fd < 0) { 234 return Status::fromStatusT(-errno); 235 } 236 237 mHandler->scheduleRunReport(new ReportRequest(args, listener, fd)); 238 239 return Status::ok(); 240 } 241 242 Status IncidentService::systemRunning() { 243 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) { 244 return Status::fromExceptionCode(Status::EX_SECURITY, 245 "Only system uid can call systemRunning"); 246 } 247 248 // When system_server is up and running, schedule the dropbox task to run. 249 mHandler->scheduleSendBacklogToDropbox(); 250 251 return Status::ok(); 252 } 253 254 /** 255 * Implement our own because the default binder implementation isn't 256 * properly handling SHELL_COMMAND_TRANSACTION. 257 */ 258 status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, 259 uint32_t flags) { 260 status_t err; 261 262 switch (code) { 263 case SHELL_COMMAND_TRANSACTION: { 264 int in = data.readFileDescriptor(); 265 int out = data.readFileDescriptor(); 266 int err = data.readFileDescriptor(); 267 int argc = data.readInt32(); 268 Vector<String8> args; 269 for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 270 args.add(String8(data.readString16())); 271 } 272 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder()); 273 sp<IResultReceiver> resultReceiver = 274 IResultReceiver::asInterface(data.readStrongBinder()); 275 276 FILE* fin = fdopen(in, "r"); 277 FILE* fout = fdopen(out, "w"); 278 FILE* ferr = fdopen(err, "w"); 279 280 if (fin == NULL || fout == NULL || ferr == NULL) { 281 resultReceiver->send(NO_MEMORY); 282 } else { 283 err = command(fin, fout, ferr, args); 284 resultReceiver->send(err); 285 } 286 287 if (fin != NULL) { 288 fflush(fin); 289 fclose(fin); 290 } 291 if (fout != NULL) { 292 fflush(fout); 293 fclose(fout); 294 } 295 if (fout != NULL) { 296 fflush(ferr); 297 fclose(ferr); 298 } 299 300 return NO_ERROR; 301 } 302 default: { return BnIncidentManager::onTransact(code, data, reply, flags); } 303 } 304 } 305 306 status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { 307 const int argCount = args.size(); 308 309 if (argCount >= 1) { 310 if (!args[0].compare(String8("privacy"))) { 311 return cmd_privacy(in, out, err, args); 312 } 313 if (!args[0].compare(String8("throttler"))) { 314 mThrottler->dump(out); 315 return NO_ERROR; 316 } 317 } 318 return cmd_help(out); 319 } 320 321 status_t IncidentService::cmd_help(FILE* out) { 322 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n"); 323 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n"); 324 fprintf(out, " Prints/parses for the section id.\n"); 325 fprintf(out, "\n"); 326 fprintf(out, "usage: adb shell cmd incident throttler\n"); 327 fprintf(out, " Prints the current throttler state\n"); 328 return NO_ERROR; 329 } 330 331 static void printPrivacy(const Privacy* p, FILE* out, String8 indent) { 332 if (p == NULL) return; 333 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest); 334 if (p->children == NULL) return; 335 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated. 336 printPrivacy(p->children[i], out, indent + " "); 337 } 338 } 339 340 status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) { 341 const int argCount = args.size(); 342 if (argCount >= 3) { 343 String8 opt = args[1]; 344 int sectionId = atoi(args[2].string()); 345 346 const Privacy* p = get_privacy_of_section(sectionId); 347 if (p == NULL) { 348 fprintf(err, "Can't find section id %d\n", sectionId); 349 return NO_ERROR; 350 } 351 fprintf(err, "Get privacy for %d\n", sectionId); 352 if (opt == "print") { 353 printPrivacy(p, out, String8("")); 354 } else if (opt == "parse") { 355 FdBuffer buf; 356 status_t error = buf.read(fileno(in), 60000); 357 if (error != NO_ERROR) { 358 fprintf(err, "Error reading from stdin\n"); 359 return error; 360 } 361 fprintf(err, "Read %zu bytes\n", buf.size()); 362 PrivacyBuffer pBuf(p, buf.data()); 363 364 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1); 365 error = pBuf.strip(spec); 366 if (error != NO_ERROR) { 367 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest); 368 return error; 369 } 370 return pBuf.flush(fileno(out)); 371 } 372 } else { 373 return cmd_help(out); 374 } 375 return NO_ERROR; 376 } 377 378 } // namespace incidentd 379 } // namespace os 380 } // namespace android 381