blob: b23c1eda87b389ecfe2fcb95a2f5811543ed4355 [file] [log] [blame]
Joe Onorato1754d742016-11-21 17:51:35 -08001/*
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 */
Yi Jin4e843102018-02-14 15:36:18 -080016#define DEBUG false
Yi Jinb592e3b2018-02-01 15:17:04 -080017#include "Log.h"
Joe Onorato1754d742016-11-21 17:51:35 -080018
19#include "IncidentService.h"
20
Yi Jinb592e3b2018-02-01 15:17:04 -080021#include "FdBuffer.h"
22#include "PrivacyBuffer.h"
Joe Onorato1754d742016-11-21 17:51:35 -080023#include "Reporter.h"
Yi Jinb592e3b2018-02-01 15:17:04 -080024#include "incidentd_util.h"
25#include "section_list.h"
Joe Onorato1754d742016-11-21 17:51:35 -080026
Mike Ma85434ec2018-11-27 10:32:31 -080027#include <android/os/IncidentReportArgs.h>
Joe Onorato1754d742016-11-21 17:51:35 -080028#include <binder/IPCThreadState.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080029#include <binder/IResultReceiver.h>
Joe Onorato1754d742016-11-21 17:51:35 -080030#include <binder/IServiceManager.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080031#include <binder/IShellCallback.h>
Joe Onorato1754d742016-11-21 17:51:35 -080032#include <cutils/log.h>
33#include <private/android_filesystem_config.h>
34#include <utils/Looper.h>
35
36#include <unistd.h>
37
Yi Jinb592e3b2018-02-01 15:17:04 -080038enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
Joe Onorato1754d742016-11-21 17:51:35 -080039
Joe Onorato1754d742016-11-21 17:51:35 -080040#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
41
Yi Jin4e843102018-02-14 15:36:18 -080042#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB
43#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
44
Mike Ma85434ec2018-11-27 10:32:31 -080045// Skip logs (1100 - 1108) because they are already in the bug report
46// Skip 1200, 1201, 1202, 3018 because they take too long
47// TODO(120079956): Skip 3008, 3015 because of error
48#define SKIPPED_SECTIONS { 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
49 1200, 1201, 1202, /* Native, hal, java traces */ \
50 3008, /* "package --proto" */ \
51 3015, /* "activity --proto processes" */ \
52 3018 /* "meminfo -a --proto" */ }
53
Yi Jin6cacbcb2018-03-30 14:04:52 -070054namespace android {
55namespace os {
56namespace incidentd {
57
Joe Onorato1754d742016-11-21 17:51:35 -080058String16 const DUMP_PERMISSION("android.permission.DUMP");
59String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
60
Yi Jinb592e3b2018-02-01 15:17:04 -080061static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080062 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080063 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080064 if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
65 // root doesn't have permission.DUMP if don't do this!
66 return Status::ok();
67 }
68
Yi Jin4bab3a12018-01-10 16:50:59 -080069 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080070 if (!checkCallingPermission(DUMP_PERMISSION)) {
71 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080072 callingPid, callingUid);
73 return Status::fromExceptionCode(
74 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080075 "Calling process does not have permission: android.permission.DUMP");
76 }
77 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
78 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
Yi Jinb592e3b2018-02-01 15:17:04 -080079 callingPid, callingUid);
80 return Status::fromExceptionCode(
81 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080082 "Calling process does not have permission: android.permission.USAGE_STATS");
83 }
Yi Jin4bab3a12018-01-10 16:50:59 -080084
85 // checking calling request uid permission.
Yi Jin4bab3a12018-01-10 16:50:59 -080086 switch (args.dest()) {
87 case DEST_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080088 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
89 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080090 callingPid, callingUid);
91 return Status::fromExceptionCode(
92 Status::EX_SECURITY,
93 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -080094 }
Bookatzda9b8d02018-11-14 13:14:45 -080095 break;
Yi Jin4bab3a12018-01-10 16:50:59 -080096 case DEST_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -080097 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
Bookatzda9b8d02018-11-14 13:14:45 -080098 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -080099 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -0800100 callingPid, callingUid);
101 return Status::fromExceptionCode(
102 Status::EX_SECURITY,
103 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800104 }
Bookatzda9b8d02018-11-14 13:14:45 -0800105 break;
Yi Jin4bab3a12018-01-10 16:50:59 -0800106 }
Joe Onorato1754d742016-11-21 17:51:35 -0800107 return Status::ok();
108}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700109
Joe Onorato1754d742016-11-21 17:51:35 -0800110// ================================================================================
Yi Jinb592e3b2018-02-01 15:17:04 -0800111ReportRequestQueue::ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800112
Yi Jinb592e3b2018-02-01 15:17:04 -0800113ReportRequestQueue::~ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800114
Yi Jinb592e3b2018-02-01 15:17:04 -0800115void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800116 unique_lock<mutex> lock(mLock);
117 mQueue.push_back(request);
118}
119
Yi Jinb592e3b2018-02-01 15:17:04 -0800120sp<ReportRequest> ReportRequestQueue::getNextRequest() {
Joe Onorato1754d742016-11-21 17:51:35 -0800121 unique_lock<mutex> lock(mLock);
122 if (mQueue.empty()) {
123 return NULL;
124 } else {
125 sp<ReportRequest> front(mQueue.front());
126 mQueue.pop_front();
127 return front;
128 }
129}
130
Joe Onorato1754d742016-11-21 17:51:35 -0800131// ================================================================================
Yi Jin4e843102018-02-14 15:36:18 -0800132ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
133 const sp<Throttler>& throttler)
134 : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
135 mHandlerLooper(handlerLooper),
136 mQueue(queue),
137 mThrottler(throttler) {}
Joe Onorato1754d742016-11-21 17:51:35 -0800138
Yi Jinb592e3b2018-02-01 15:17:04 -0800139ReportHandler::~ReportHandler() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800140
Yi Jinb592e3b2018-02-01 15:17:04 -0800141void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800142 switch (message.what) {
143 case WHAT_RUN_REPORT:
144 run_report();
145 break;
146 case WHAT_SEND_BACKLOG_TO_DROPBOX:
147 send_backlog_to_dropbox();
148 break;
149 }
150}
151
Yi Jinb592e3b2018-02-01 15:17:04 -0800152void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800153 mQueue->addRequest(request);
154 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
155 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
156}
157
Yi Jinb592e3b2018-02-01 15:17:04 -0800158void ReportHandler::scheduleSendBacklogToDropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800159 unique_lock<mutex> lock(mLock);
160 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
161 schedule_send_backlog_to_dropbox_locked();
162}
163
Yi Jinb592e3b2018-02-01 15:17:04 -0800164void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
Joe Onorato1754d742016-11-21 17:51:35 -0800165 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
Yi Jinb592e3b2018-02-01 15:17:04 -0800166 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
Joe Onorato1754d742016-11-21 17:51:35 -0800167}
168
Yi Jinb592e3b2018-02-01 15:17:04 -0800169void ReportHandler::run_report() {
Joe Onorato1754d742016-11-21 17:51:35 -0800170 sp<Reporter> reporter = new Reporter();
171
172 // Merge all of the requests into one that has all of the
173 // requested fields.
174 while (true) {
175 sp<ReportRequest> request = mQueue->getNextRequest();
176 if (request == NULL) {
177 break;
178 }
179 reporter->batch.add(request);
Joe Onorato1754d742016-11-21 17:51:35 -0800180 }
181
Yi Jin4e843102018-02-14 15:36:18 -0800182 if (mThrottler->shouldThrottle()) {
183 ALOGW("RunReport got throttled.");
184 return;
185 }
186
Joe Onorato1754d742016-11-21 17:51:35 -0800187 // Take the report, which might take a while. More requests might queue
188 // up while we're doing this, and we'll handle them in their next batch.
189 // TODO: We should further rate-limit the reports to no more than N per time-period.
Yi Jin4e843102018-02-14 15:36:18 -0800190 size_t reportByteSize = 0;
191 Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
192 mThrottler->addReportSize(reportByteSize);
Joe Onorato1754d742016-11-21 17:51:35 -0800193 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
194 unique_lock<mutex> lock(mLock);
195 schedule_send_backlog_to_dropbox_locked();
196 }
197}
198
Yi Jinb592e3b2018-02-01 15:17:04 -0800199void ReportHandler::send_backlog_to_dropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800200 if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
201 // There was a failure. Exponential backoff.
202 unique_lock<mutex> lock(mLock);
203 mBacklogDelay *= 2;
204 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800205 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato1754d742016-11-21 17:51:35 -0800206 schedule_send_backlog_to_dropbox_locked();
207 } else {
208 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
209 }
210}
211
212// ================================================================================
213IncidentService::IncidentService(const sp<Looper>& handlerLooper)
Yi Jin4e843102018-02-14 15:36:18 -0800214 : mQueue(new ReportRequestQueue()),
215 mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
216 mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
Joe Onorato1754d742016-11-21 17:51:35 -0800217}
218
Yi Jinb592e3b2018-02-01 15:17:04 -0800219IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800220
Yi Jinb592e3b2018-02-01 15:17:04 -0800221Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato1754d742016-11-21 17:51:35 -0800222 ALOGI("reportIncident");
223
Yi Jin4bab3a12018-01-10 16:50:59 -0800224 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800225 if (!status.isOk()) {
226 return status;
227 }
228
229 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
230
231 return Status::ok();
232}
233
Yi Jinb592e3b2018-02-01 15:17:04 -0800234Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
235 const sp<IIncidentReportStatusListener>& listener,
236 const unique_fd& stream) {
Joe Onorato1754d742016-11-21 17:51:35 -0800237 ALOGI("reportIncidentToStream");
238
Yi Jin4bab3a12018-01-10 16:50:59 -0800239 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800240 if (!status.isOk()) {
241 return status;
242 }
243
244 int fd = dup(stream.get());
245 if (fd < 0) {
246 return Status::fromStatusT(-errno);
247 }
248
249 mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
250
251 return Status::ok();
252}
253
Yi Jinb592e3b2018-02-01 15:17:04 -0800254Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800255 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
256 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800257 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800258 }
Yi Jinadd11e92017-07-30 16:10:07 -0700259
Joe Onorato1754d742016-11-21 17:51:35 -0800260 // When system_server is up and running, schedule the dropbox task to run.
261 mHandler->scheduleSendBacklogToDropbox();
262
263 return Status::ok();
264}
265
Yi Jinb592e3b2018-02-01 15:17:04 -0800266/**
267 * Implement our own because the default binder implementation isn't
268 * properly handling SHELL_COMMAND_TRANSACTION.
269 */
270status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
271 uint32_t flags) {
272 status_t err;
273
274 switch (code) {
275 case SHELL_COMMAND_TRANSACTION: {
276 int in = data.readFileDescriptor();
277 int out = data.readFileDescriptor();
278 int err = data.readFileDescriptor();
279 int argc = data.readInt32();
280 Vector<String8> args;
281 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
282 args.add(String8(data.readString16()));
283 }
284 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
285 sp<IResultReceiver> resultReceiver =
286 IResultReceiver::asInterface(data.readStrongBinder());
287
288 FILE* fin = fdopen(in, "r");
289 FILE* fout = fdopen(out, "w");
290 FILE* ferr = fdopen(err, "w");
291
292 if (fin == NULL || fout == NULL || ferr == NULL) {
293 resultReceiver->send(NO_MEMORY);
294 } else {
295 err = command(fin, fout, ferr, args);
296 resultReceiver->send(err);
297 }
298
299 if (fin != NULL) {
300 fflush(fin);
301 fclose(fin);
302 }
303 if (fout != NULL) {
304 fflush(fout);
305 fclose(fout);
306 }
307 if (fout != NULL) {
308 fflush(ferr);
309 fclose(ferr);
310 }
311
312 return NO_ERROR;
Bookatzda9b8d02018-11-14 13:14:45 -0800313 } break;
Yi Jinb592e3b2018-02-01 15:17:04 -0800314 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
315 }
316}
317
318status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
319 const int argCount = args.size();
320
321 if (argCount >= 1) {
322 if (!args[0].compare(String8("privacy"))) {
323 return cmd_privacy(in, out, err, args);
324 }
Yi Jin4e843102018-02-14 15:36:18 -0800325 if (!args[0].compare(String8("throttler"))) {
326 mThrottler->dump(out);
327 return NO_ERROR;
328 }
Yi Jin908c02f2018-06-22 16:51:40 -0700329 if (!args[0].compare(String8("section"))) {
330 int id = atoi(args[1]);
331 int idx = 0;
332 while (SECTION_LIST[idx] != NULL) {
333 const Section* section = SECTION_LIST[idx];
334 if (section->id == id) {
335 fprintf(out, "Section[%d] %s\n", id, section->name.string());
336 break;
337 }
338 idx++;
339 }
340 return NO_ERROR;
341 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800342 }
343 return cmd_help(out);
344}
345
346status_t IncidentService::cmd_help(FILE* out) {
347 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
348 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700349 fprintf(out, " Prints/parses for the section id.\n\n");
350 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
351 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800352 fprintf(out, "usage: adb shell cmd incident throttler\n");
353 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800354 return NO_ERROR;
355}
356
357static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
358 if (p == NULL) return;
359 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
360 if (p->children == NULL) return;
361 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
362 printPrivacy(p->children[i], out, indent + " ");
363 }
364}
365
366status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
367 const int argCount = args.size();
368 if (argCount >= 3) {
369 String8 opt = args[1];
370 int sectionId = atoi(args[2].string());
371
372 const Privacy* p = get_privacy_of_section(sectionId);
373 if (p == NULL) {
374 fprintf(err, "Can't find section id %d\n", sectionId);
375 return NO_ERROR;
376 }
377 fprintf(err, "Get privacy for %d\n", sectionId);
378 if (opt == "print") {
379 printPrivacy(p, out, String8(""));
380 } else if (opt == "parse") {
381 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700382 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800383 if (error != NO_ERROR) {
384 fprintf(err, "Error reading from stdin\n");
385 return error;
386 }
387 fprintf(err, "Read %zu bytes\n", buf.size());
Yi Jin86dce412018-03-07 11:36:57 -0800388 PrivacyBuffer pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800389
390 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
391 error = pBuf.strip(spec);
392 if (error != NO_ERROR) {
393 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
394 return error;
395 }
396 return pBuf.flush(fileno(out));
397 }
398 } else {
399 return cmd_help(out);
400 }
401 return NO_ERROR;
402}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700403
Mike Ma85434ec2018-11-27 10:32:31 -0800404status_t IncidentService::dump(int fd, const Vector<String16>& args) {
405 if (std::find(args.begin(), args.end(), String16("--proto")) == args.end()) {
406 ALOGD("Skip dumping incident. Only proto format is supported.");
407 dprintf(fd, "Incident dump only supports proto version.\n");
408 return NO_ERROR;
409 }
410
411 ALOGD("Dump incident proto");
412 IncidentReportArgs incidentArgs;
413 incidentArgs.setDest(DEST_EXPLICIT);
414 int skipped[] = SKIPPED_SECTIONS;
415 for (const Section** section = SECTION_LIST; *section; section++) {
416 const int id = (*section)->id;
417 if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)) {
418 incidentArgs.addSection(id);
419 }
420 }
421
422 if (!checkIncidentPermissions(incidentArgs).isOk()) {
423 return PERMISSION_DENIED;
424 }
425
426 int fd1 = dup(fd);
427 if (fd1 < 0) {
428 return -errno;
429 }
430
431 mHandler->scheduleRunReport(new ReportRequest(incidentArgs, NULL, fd1));
432
433 return NO_ERROR;
434}
435
Yi Jin6cacbcb2018-03-30 14:04:52 -0700436} // namespace incidentd
437} // namespace os
438} // namespace android