blob: d02b4dd99067ea69b41553b6cac483dd821c8026 [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
27#include <binder/IPCThreadState.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080028#include <binder/IResultReceiver.h>
Joe Onorato1754d742016-11-21 17:51:35 -080029#include <binder/IServiceManager.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080030#include <binder/IShellCallback.h>
Joe Onorato1754d742016-11-21 17:51:35 -080031#include <cutils/log.h>
32#include <private/android_filesystem_config.h>
33#include <utils/Looper.h>
34
35#include <unistd.h>
36
37using namespace android;
Yi Jinb592e3b2018-02-01 15:17:04 -080038using namespace android::base;
Joe Onorato1754d742016-11-21 17:51:35 -080039
Yi Jinb592e3b2018-02-01 15:17:04 -080040enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
Joe Onorato1754d742016-11-21 17:51:35 -080041
Joe Onorato1754d742016-11-21 17:51:35 -080042#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
43
Yi Jin4e843102018-02-14 15:36:18 -080044#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB
45#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
46
Joe Onorato1754d742016-11-21 17:51:35 -080047// ================================================================================
48String16 const DUMP_PERMISSION("android.permission.DUMP");
49String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
50
Yi Jinb592e3b2018-02-01 15:17:04 -080051static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080052 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080053 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080054 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
Yi Jin4bab3a12018-01-10 16:50:59 -080059 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080060 if (!checkCallingPermission(DUMP_PERMISSION)) {
61 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080062 callingPid, callingUid);
63 return Status::fromExceptionCode(
64 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080065 "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",
Yi Jinb592e3b2018-02-01 15:17:04 -080069 callingPid, callingUid);
70 return Status::fromExceptionCode(
71 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080072 "Calling process does not have permission: android.permission.USAGE_STATS");
73 }
Yi Jin4bab3a12018-01-10 16:50:59 -080074
75 // checking calling request uid permission.
Yi Jin4bab3a12018-01-10 16:50:59 -080076 switch (args.dest()) {
77 case DEST_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080078 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
79 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080080 callingPid, callingUid);
81 return Status::fromExceptionCode(
82 Status::EX_SECURITY,
83 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -080084 }
85 case DEST_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -080086 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
87 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -080088 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080089 callingPid, callingUid);
90 return Status::fromExceptionCode(
91 Status::EX_SECURITY,
92 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -080093 }
94 }
Joe Onorato1754d742016-11-21 17:51:35 -080095 return Status::ok();
96}
Joe Onorato1754d742016-11-21 17:51:35 -080097// ================================================================================
Yi Jinb592e3b2018-02-01 15:17:04 -080098ReportRequestQueue::ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -080099
Yi Jinb592e3b2018-02-01 15:17:04 -0800100ReportRequestQueue::~ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800101
Yi Jinb592e3b2018-02-01 15:17:04 -0800102void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800103 unique_lock<mutex> lock(mLock);
104 mQueue.push_back(request);
105}
106
Yi Jinb592e3b2018-02-01 15:17:04 -0800107sp<ReportRequest> ReportRequestQueue::getNextRequest() {
Joe Onorato1754d742016-11-21 17:51:35 -0800108 unique_lock<mutex> lock(mLock);
109 if (mQueue.empty()) {
110 return NULL;
111 } else {
112 sp<ReportRequest> front(mQueue.front());
113 mQueue.pop_front();
114 return front;
115 }
116}
117
Joe Onorato1754d742016-11-21 17:51:35 -0800118// ================================================================================
Yi Jin4e843102018-02-14 15:36:18 -0800119ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
120 const sp<Throttler>& throttler)
121 : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
122 mHandlerLooper(handlerLooper),
123 mQueue(queue),
124 mThrottler(throttler) {}
Joe Onorato1754d742016-11-21 17:51:35 -0800125
Yi Jinb592e3b2018-02-01 15:17:04 -0800126ReportHandler::~ReportHandler() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800127
Yi Jinb592e3b2018-02-01 15:17:04 -0800128void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800129 switch (message.what) {
130 case WHAT_RUN_REPORT:
131 run_report();
132 break;
133 case WHAT_SEND_BACKLOG_TO_DROPBOX:
134 send_backlog_to_dropbox();
135 break;
136 }
137}
138
Yi Jinb592e3b2018-02-01 15:17:04 -0800139void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800140 mQueue->addRequest(request);
141 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
142 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
143}
144
Yi Jinb592e3b2018-02-01 15:17:04 -0800145void ReportHandler::scheduleSendBacklogToDropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800146 unique_lock<mutex> lock(mLock);
147 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
148 schedule_send_backlog_to_dropbox_locked();
149}
150
Yi Jinb592e3b2018-02-01 15:17:04 -0800151void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
Joe Onorato1754d742016-11-21 17:51:35 -0800152 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
Yi Jinb592e3b2018-02-01 15:17:04 -0800153 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
Joe Onorato1754d742016-11-21 17:51:35 -0800154}
155
Yi Jinb592e3b2018-02-01 15:17:04 -0800156void ReportHandler::run_report() {
Joe Onorato1754d742016-11-21 17:51:35 -0800157 sp<Reporter> reporter = new Reporter();
158
159 // Merge all of the requests into one that has all of the
160 // requested fields.
161 while (true) {
162 sp<ReportRequest> request = mQueue->getNextRequest();
163 if (request == NULL) {
164 break;
165 }
166 reporter->batch.add(request);
Joe Onorato1754d742016-11-21 17:51:35 -0800167 }
168
Yi Jin4e843102018-02-14 15:36:18 -0800169 if (mThrottler->shouldThrottle()) {
170 ALOGW("RunReport got throttled.");
171 return;
172 }
173
Joe Onorato1754d742016-11-21 17:51:35 -0800174 // Take the report, which might take a while. More requests might queue
175 // up while we're doing this, and we'll handle them in their next batch.
176 // TODO: We should further rate-limit the reports to no more than N per time-period.
Yi Jin4e843102018-02-14 15:36:18 -0800177 size_t reportByteSize = 0;
178 Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
179 mThrottler->addReportSize(reportByteSize);
Joe Onorato1754d742016-11-21 17:51:35 -0800180 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
181 unique_lock<mutex> lock(mLock);
182 schedule_send_backlog_to_dropbox_locked();
183 }
184}
185
Yi Jinb592e3b2018-02-01 15:17:04 -0800186void ReportHandler::send_backlog_to_dropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800187 if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
188 // There was a failure. Exponential backoff.
189 unique_lock<mutex> lock(mLock);
190 mBacklogDelay *= 2;
191 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800192 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato1754d742016-11-21 17:51:35 -0800193 schedule_send_backlog_to_dropbox_locked();
194 } else {
195 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
196 }
197}
198
199// ================================================================================
200IncidentService::IncidentService(const sp<Looper>& handlerLooper)
Yi Jin4e843102018-02-14 15:36:18 -0800201 : mQueue(new ReportRequestQueue()),
202 mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
203 mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
Joe Onorato1754d742016-11-21 17:51:35 -0800204}
205
Yi Jinb592e3b2018-02-01 15:17:04 -0800206IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800207
Yi Jinb592e3b2018-02-01 15:17:04 -0800208Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato1754d742016-11-21 17:51:35 -0800209 ALOGI("reportIncident");
210
Yi Jin4bab3a12018-01-10 16:50:59 -0800211 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800212 if (!status.isOk()) {
213 return status;
214 }
215
216 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
217
218 return Status::ok();
219}
220
Yi Jinb592e3b2018-02-01 15:17:04 -0800221Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
222 const sp<IIncidentReportStatusListener>& listener,
223 const unique_fd& stream) {
Joe Onorato1754d742016-11-21 17:51:35 -0800224 ALOGI("reportIncidentToStream");
225
Yi Jin4bab3a12018-01-10 16:50:59 -0800226 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800227 if (!status.isOk()) {
228 return status;
229 }
230
231 int fd = dup(stream.get());
232 if (fd < 0) {
233 return Status::fromStatusT(-errno);
234 }
235
236 mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
237
238 return Status::ok();
239}
240
Yi Jinb592e3b2018-02-01 15:17:04 -0800241Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800242 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
243 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800244 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800245 }
Yi Jinadd11e92017-07-30 16:10:07 -0700246
Joe Onorato1754d742016-11-21 17:51:35 -0800247 // When system_server is up and running, schedule the dropbox task to run.
248 mHandler->scheduleSendBacklogToDropbox();
249
250 return Status::ok();
251}
252
Yi Jinb592e3b2018-02-01 15:17:04 -0800253/**
254 * Implement our own because the default binder implementation isn't
255 * properly handling SHELL_COMMAND_TRANSACTION.
256 */
257status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
258 uint32_t flags) {
259 status_t err;
260
261 switch (code) {
262 case SHELL_COMMAND_TRANSACTION: {
263 int in = data.readFileDescriptor();
264 int out = data.readFileDescriptor();
265 int err = data.readFileDescriptor();
266 int argc = data.readInt32();
267 Vector<String8> args;
268 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
269 args.add(String8(data.readString16()));
270 }
271 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
272 sp<IResultReceiver> resultReceiver =
273 IResultReceiver::asInterface(data.readStrongBinder());
274
275 FILE* fin = fdopen(in, "r");
276 FILE* fout = fdopen(out, "w");
277 FILE* ferr = fdopen(err, "w");
278
279 if (fin == NULL || fout == NULL || ferr == NULL) {
280 resultReceiver->send(NO_MEMORY);
281 } else {
282 err = command(fin, fout, ferr, args);
283 resultReceiver->send(err);
284 }
285
286 if (fin != NULL) {
287 fflush(fin);
288 fclose(fin);
289 }
290 if (fout != NULL) {
291 fflush(fout);
292 fclose(fout);
293 }
294 if (fout != NULL) {
295 fflush(ferr);
296 fclose(ferr);
297 }
298
299 return NO_ERROR;
300 }
301 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
302 }
303}
304
305status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
306 const int argCount = args.size();
307
308 if (argCount >= 1) {
309 if (!args[0].compare(String8("privacy"))) {
310 return cmd_privacy(in, out, err, args);
311 }
Yi Jin4e843102018-02-14 15:36:18 -0800312 if (!args[0].compare(String8("throttler"))) {
313 mThrottler->dump(out);
314 return NO_ERROR;
315 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800316 }
317 return cmd_help(out);
318}
319
320status_t IncidentService::cmd_help(FILE* out) {
321 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
322 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
323 fprintf(out, " Prints/parses for the section id.\n");
Yi Jin4e843102018-02-14 15:36:18 -0800324 fprintf(out, "\n");
325 fprintf(out, "usage: adb shell cmd incident throttler\n");
326 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800327 return NO_ERROR;
328}
329
330static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
331 if (p == NULL) return;
332 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
333 if (p->children == NULL) return;
334 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
335 printPrivacy(p->children[i], out, indent + " ");
336 }
337}
338
339status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
340 const int argCount = args.size();
341 if (argCount >= 3) {
342 String8 opt = args[1];
343 int sectionId = atoi(args[2].string());
344
345 const Privacy* p = get_privacy_of_section(sectionId);
346 if (p == NULL) {
347 fprintf(err, "Can't find section id %d\n", sectionId);
348 return NO_ERROR;
349 }
350 fprintf(err, "Get privacy for %d\n", sectionId);
351 if (opt == "print") {
352 printPrivacy(p, out, String8(""));
353 } else if (opt == "parse") {
354 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700355 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800356 if (error != NO_ERROR) {
357 fprintf(err, "Error reading from stdin\n");
358 return error;
359 }
360 fprintf(err, "Read %zu bytes\n", buf.size());
Yi Jin86dce412018-03-07 11:36:57 -0800361 PrivacyBuffer pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800362
363 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
364 error = pBuf.strip(spec);
365 if (error != NO_ERROR) {
366 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
367 return error;
368 }
369 return pBuf.flush(fileno(out));
370 }
371 } else {
372 return cmd_help(out);
373 }
374 return NO_ERROR;
375}