blob: f8fb4a676ba0ddd4dccb07f1d285899e564046e8 [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>
Mike Ma35056662018-12-06 13:32:59 -080032#include <log/log.h>
Joe Onorato1754d742016-11-21 17:51:35 -080033#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 Ma28381692018-12-04 15:46:29 -080045// Skip these sections for dumpstate only. Dumpstate allows 10s max for each service to dump.
46// Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report.
47// Skip 3018 because it takes too long.
Mike Ma85434ec2018-11-27 10:32:31 -080048#define SKIPPED_SECTIONS { 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
49 1200, 1201, 1202, /* Native, hal, java traces */ \
Mike Ma85434ec2018-11-27 10:32:31 -080050 3018 /* "meminfo -a --proto" */ }
51
Yi Jin6cacbcb2018-03-30 14:04:52 -070052namespace android {
53namespace os {
54namespace incidentd {
55
Joe Onorato1754d742016-11-21 17:51:35 -080056String16 const DUMP_PERMISSION("android.permission.DUMP");
57String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
58
Yi Jinb592e3b2018-02-01 15:17:04 -080059static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080060 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080061 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080062 if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
63 // root doesn't have permission.DUMP if don't do this!
64 return Status::ok();
65 }
66
Yi Jin4bab3a12018-01-10 16:50:59 -080067 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080068 if (!checkCallingPermission(DUMP_PERMISSION)) {
69 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080070 callingPid, callingUid);
71 return Status::fromExceptionCode(
72 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080073 "Calling process does not have permission: android.permission.DUMP");
74 }
75 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
76 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
Yi Jinb592e3b2018-02-01 15:17:04 -080077 callingPid, callingUid);
78 return Status::fromExceptionCode(
79 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080080 "Calling process does not have permission: android.permission.USAGE_STATS");
81 }
Yi Jin4bab3a12018-01-10 16:50:59 -080082
83 // checking calling request uid permission.
Yi Jin4bab3a12018-01-10 16:50:59 -080084 switch (args.dest()) {
85 case DEST_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080086 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
87 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080088 callingPid, callingUid);
89 return Status::fromExceptionCode(
90 Status::EX_SECURITY,
91 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -080092 }
Bookatzda9b8d02018-11-14 13:14:45 -080093 break;
Yi Jin4bab3a12018-01-10 16:50:59 -080094 case DEST_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -080095 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
Bookatzda9b8d02018-11-14 13:14:45 -080096 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -080097 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080098 callingPid, callingUid);
99 return Status::fromExceptionCode(
100 Status::EX_SECURITY,
101 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800102 }
Bookatzda9b8d02018-11-14 13:14:45 -0800103 break;
Yi Jin4bab3a12018-01-10 16:50:59 -0800104 }
Joe Onorato1754d742016-11-21 17:51:35 -0800105 return Status::ok();
106}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700107
Joe Onorato1754d742016-11-21 17:51:35 -0800108// ================================================================================
Yi Jinb592e3b2018-02-01 15:17:04 -0800109ReportRequestQueue::ReportRequestQueue() {}
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 -0800113void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800114 unique_lock<mutex> lock(mLock);
115 mQueue.push_back(request);
116}
117
Yi Jinb592e3b2018-02-01 15:17:04 -0800118sp<ReportRequest> ReportRequestQueue::getNextRequest() {
Joe Onorato1754d742016-11-21 17:51:35 -0800119 unique_lock<mutex> lock(mLock);
120 if (mQueue.empty()) {
121 return NULL;
122 } else {
123 sp<ReportRequest> front(mQueue.front());
124 mQueue.pop_front();
125 return front;
126 }
127}
128
Joe Onorato1754d742016-11-21 17:51:35 -0800129// ================================================================================
Yi Jin4e843102018-02-14 15:36:18 -0800130ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
131 const sp<Throttler>& throttler)
132 : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
133 mHandlerLooper(handlerLooper),
134 mQueue(queue),
135 mThrottler(throttler) {}
Joe Onorato1754d742016-11-21 17:51:35 -0800136
Yi Jinb592e3b2018-02-01 15:17:04 -0800137ReportHandler::~ReportHandler() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800138
Yi Jinb592e3b2018-02-01 15:17:04 -0800139void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800140 switch (message.what) {
141 case WHAT_RUN_REPORT:
142 run_report();
143 break;
144 case WHAT_SEND_BACKLOG_TO_DROPBOX:
145 send_backlog_to_dropbox();
146 break;
147 }
148}
149
Yi Jinb592e3b2018-02-01 15:17:04 -0800150void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800151 mQueue->addRequest(request);
152 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
153 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
154}
155
Yi Jinb592e3b2018-02-01 15:17:04 -0800156void ReportHandler::scheduleSendBacklogToDropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800157 unique_lock<mutex> lock(mLock);
158 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
159 schedule_send_backlog_to_dropbox_locked();
160}
161
Yi Jinb592e3b2018-02-01 15:17:04 -0800162void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
Joe Onorato1754d742016-11-21 17:51:35 -0800163 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
Yi Jinb592e3b2018-02-01 15:17:04 -0800164 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
Joe Onorato1754d742016-11-21 17:51:35 -0800165}
166
Yi Jinb592e3b2018-02-01 15:17:04 -0800167void ReportHandler::run_report() {
Joe Onorato1754d742016-11-21 17:51:35 -0800168 sp<Reporter> reporter = new Reporter();
169
170 // Merge all of the requests into one that has all of the
171 // requested fields.
172 while (true) {
173 sp<ReportRequest> request = mQueue->getNextRequest();
174 if (request == NULL) {
175 break;
176 }
177 reporter->batch.add(request);
Joe Onorato1754d742016-11-21 17:51:35 -0800178 }
179
Yi Jin4e843102018-02-14 15:36:18 -0800180 if (mThrottler->shouldThrottle()) {
181 ALOGW("RunReport got throttled.");
182 return;
183 }
184
Joe Onorato1754d742016-11-21 17:51:35 -0800185 // Take the report, which might take a while. More requests might queue
186 // up while we're doing this, and we'll handle them in their next batch.
187 // TODO: We should further rate-limit the reports to no more than N per time-period.
Yi Jin4e843102018-02-14 15:36:18 -0800188 size_t reportByteSize = 0;
189 Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
190 mThrottler->addReportSize(reportByteSize);
Joe Onorato1754d742016-11-21 17:51:35 -0800191 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
192 unique_lock<mutex> lock(mLock);
193 schedule_send_backlog_to_dropbox_locked();
194 }
195}
196
Yi Jinb592e3b2018-02-01 15:17:04 -0800197void ReportHandler::send_backlog_to_dropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800198 if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
199 // There was a failure. Exponential backoff.
200 unique_lock<mutex> lock(mLock);
201 mBacklogDelay *= 2;
202 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800203 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato1754d742016-11-21 17:51:35 -0800204 schedule_send_backlog_to_dropbox_locked();
205 } else {
206 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
207 }
208}
209
210// ================================================================================
211IncidentService::IncidentService(const sp<Looper>& handlerLooper)
Yi Jin4e843102018-02-14 15:36:18 -0800212 : mQueue(new ReportRequestQueue()),
213 mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
214 mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
Joe Onorato1754d742016-11-21 17:51:35 -0800215}
216
Yi Jinb592e3b2018-02-01 15:17:04 -0800217IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800218
Yi Jinb592e3b2018-02-01 15:17:04 -0800219Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato1754d742016-11-21 17:51:35 -0800220 ALOGI("reportIncident");
221
Yi Jin4bab3a12018-01-10 16:50:59 -0800222 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800223 if (!status.isOk()) {
224 return status;
225 }
226
227 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
228
229 return Status::ok();
230}
231
Yi Jinb592e3b2018-02-01 15:17:04 -0800232Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
233 const sp<IIncidentReportStatusListener>& listener,
234 const unique_fd& stream) {
Joe Onorato1754d742016-11-21 17:51:35 -0800235 ALOGI("reportIncidentToStream");
236
Yi Jin4bab3a12018-01-10 16:50:59 -0800237 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800238 if (!status.isOk()) {
239 return status;
240 }
241
242 int fd = dup(stream.get());
243 if (fd < 0) {
244 return Status::fromStatusT(-errno);
245 }
246
247 mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
248
249 return Status::ok();
250}
251
Yi Jinb592e3b2018-02-01 15:17:04 -0800252Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800253 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
254 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800255 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800256 }
Yi Jinadd11e92017-07-30 16:10:07 -0700257
Joe Onorato1754d742016-11-21 17:51:35 -0800258 // When system_server is up and running, schedule the dropbox task to run.
259 mHandler->scheduleSendBacklogToDropbox();
260
261 return Status::ok();
262}
263
Yi Jinb592e3b2018-02-01 15:17:04 -0800264/**
265 * Implement our own because the default binder implementation isn't
266 * properly handling SHELL_COMMAND_TRANSACTION.
267 */
268status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
269 uint32_t flags) {
270 status_t err;
271
272 switch (code) {
273 case SHELL_COMMAND_TRANSACTION: {
274 int in = data.readFileDescriptor();
275 int out = data.readFileDescriptor();
276 int err = data.readFileDescriptor();
277 int argc = data.readInt32();
278 Vector<String8> args;
279 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
280 args.add(String8(data.readString16()));
281 }
282 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
283 sp<IResultReceiver> resultReceiver =
284 IResultReceiver::asInterface(data.readStrongBinder());
285
286 FILE* fin = fdopen(in, "r");
287 FILE* fout = fdopen(out, "w");
288 FILE* ferr = fdopen(err, "w");
289
290 if (fin == NULL || fout == NULL || ferr == NULL) {
291 resultReceiver->send(NO_MEMORY);
292 } else {
293 err = command(fin, fout, ferr, args);
294 resultReceiver->send(err);
295 }
296
297 if (fin != NULL) {
298 fflush(fin);
299 fclose(fin);
300 }
301 if (fout != NULL) {
302 fflush(fout);
303 fclose(fout);
304 }
305 if (fout != NULL) {
306 fflush(ferr);
307 fclose(ferr);
308 }
309
310 return NO_ERROR;
Bookatzda9b8d02018-11-14 13:14:45 -0800311 } break;
Yi Jinb592e3b2018-02-01 15:17:04 -0800312 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
313 }
314}
315
316status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
317 const int argCount = args.size();
318
319 if (argCount >= 1) {
320 if (!args[0].compare(String8("privacy"))) {
321 return cmd_privacy(in, out, err, args);
322 }
Yi Jin4e843102018-02-14 15:36:18 -0800323 if (!args[0].compare(String8("throttler"))) {
324 mThrottler->dump(out);
325 return NO_ERROR;
326 }
Yi Jin908c02f2018-06-22 16:51:40 -0700327 if (!args[0].compare(String8("section"))) {
328 int id = atoi(args[1]);
329 int idx = 0;
330 while (SECTION_LIST[idx] != NULL) {
331 const Section* section = SECTION_LIST[idx];
332 if (section->id == id) {
333 fprintf(out, "Section[%d] %s\n", id, section->name.string());
334 break;
335 }
336 idx++;
337 }
338 return NO_ERROR;
339 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800340 }
341 return cmd_help(out);
342}
343
344status_t IncidentService::cmd_help(FILE* out) {
345 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
346 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700347 fprintf(out, " Prints/parses for the section id.\n\n");
348 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
349 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800350 fprintf(out, "usage: adb shell cmd incident throttler\n");
351 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800352 return NO_ERROR;
353}
354
355static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
356 if (p == NULL) return;
357 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
358 if (p->children == NULL) return;
359 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
360 printPrivacy(p->children[i], out, indent + " ");
361 }
362}
363
364status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
365 const int argCount = args.size();
366 if (argCount >= 3) {
367 String8 opt = args[1];
368 int sectionId = atoi(args[2].string());
369
370 const Privacy* p = get_privacy_of_section(sectionId);
371 if (p == NULL) {
372 fprintf(err, "Can't find section id %d\n", sectionId);
373 return NO_ERROR;
374 }
375 fprintf(err, "Get privacy for %d\n", sectionId);
376 if (opt == "print") {
377 printPrivacy(p, out, String8(""));
378 } else if (opt == "parse") {
379 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700380 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800381 if (error != NO_ERROR) {
382 fprintf(err, "Error reading from stdin\n");
383 return error;
384 }
385 fprintf(err, "Read %zu bytes\n", buf.size());
Yi Jin86dce412018-03-07 11:36:57 -0800386 PrivacyBuffer pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800387
388 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
389 error = pBuf.strip(spec);
390 if (error != NO_ERROR) {
391 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
392 return error;
393 }
394 return pBuf.flush(fileno(out));
395 }
396 } else {
397 return cmd_help(out);
398 }
399 return NO_ERROR;
400}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700401
Mike Ma85434ec2018-11-27 10:32:31 -0800402status_t IncidentService::dump(int fd, const Vector<String16>& args) {
403 if (std::find(args.begin(), args.end(), String16("--proto")) == args.end()) {
404 ALOGD("Skip dumping incident. Only proto format is supported.");
405 dprintf(fd, "Incident dump only supports proto version.\n");
406 return NO_ERROR;
407 }
408
409 ALOGD("Dump incident proto");
410 IncidentReportArgs incidentArgs;
411 incidentArgs.setDest(DEST_EXPLICIT);
412 int skipped[] = SKIPPED_SECTIONS;
413 for (const Section** section = SECTION_LIST; *section; section++) {
414 const int id = (*section)->id;
415 if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)) {
416 incidentArgs.addSection(id);
417 }
418 }
419
420 if (!checkIncidentPermissions(incidentArgs).isOk()) {
421 return PERMISSION_DENIED;
422 }
423
424 int fd1 = dup(fd);
425 if (fd1 < 0) {
426 return -errno;
427 }
428
429 mHandler->scheduleRunReport(new ReportRequest(incidentArgs, NULL, fd1));
430
431 return NO_ERROR;
432}
433
Yi Jin6cacbcb2018-03-30 14:04:52 -0700434} // namespace incidentd
435} // namespace os
436} // namespace android