blob: e92cf9444e151ae97981799a1a9231077e10065a [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
Yi Jinb592e3b2018-02-01 15:17:04 -080037enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
Joe Onorato1754d742016-11-21 17:51:35 -080038
Joe Onorato1754d742016-11-21 17:51:35 -080039#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
40
Yi Jin4e843102018-02-14 15:36:18 -080041#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB
42#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
43
Yi Jin6cacbcb2018-03-30 14:04:52 -070044namespace android {
45namespace os {
46namespace incidentd {
47
Joe Onorato1754d742016-11-21 17:51:35 -080048String16 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}
Yi Jin6cacbcb2018-03-30 14:04:52 -070097
Joe Onorato1754d742016-11-21 17:51:35 -080098// ================================================================================
Yi Jinb592e3b2018-02-01 15:17:04 -080099ReportRequestQueue::ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800100
Yi Jinb592e3b2018-02-01 15:17:04 -0800101ReportRequestQueue::~ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800102
Yi Jinb592e3b2018-02-01 15:17:04 -0800103void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800104 unique_lock<mutex> lock(mLock);
105 mQueue.push_back(request);
106}
107
Yi Jinb592e3b2018-02-01 15:17:04 -0800108sp<ReportRequest> ReportRequestQueue::getNextRequest() {
Joe Onorato1754d742016-11-21 17:51:35 -0800109 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
Joe Onorato1754d742016-11-21 17:51:35 -0800119// ================================================================================
Yi Jin4e843102018-02-14 15:36:18 -0800120ReportHandler::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) {}
Joe Onorato1754d742016-11-21 17:51:35 -0800126
Yi Jinb592e3b2018-02-01 15:17:04 -0800127ReportHandler::~ReportHandler() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800128
Yi Jinb592e3b2018-02-01 15:17:04 -0800129void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800130 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
Yi Jinb592e3b2018-02-01 15:17:04 -0800140void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800141 mQueue->addRequest(request);
142 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
143 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
144}
145
Yi Jinb592e3b2018-02-01 15:17:04 -0800146void ReportHandler::scheduleSendBacklogToDropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800147 unique_lock<mutex> lock(mLock);
148 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
149 schedule_send_backlog_to_dropbox_locked();
150}
151
Yi Jinb592e3b2018-02-01 15:17:04 -0800152void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
Joe Onorato1754d742016-11-21 17:51:35 -0800153 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
Yi Jinb592e3b2018-02-01 15:17:04 -0800154 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
Joe Onorato1754d742016-11-21 17:51:35 -0800155}
156
Yi Jinb592e3b2018-02-01 15:17:04 -0800157void ReportHandler::run_report() {
Joe Onorato1754d742016-11-21 17:51:35 -0800158 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);
Joe Onorato1754d742016-11-21 17:51:35 -0800168 }
169
Yi Jin4e843102018-02-14 15:36:18 -0800170 if (mThrottler->shouldThrottle()) {
171 ALOGW("RunReport got throttled.");
172 return;
173 }
174
Joe Onorato1754d742016-11-21 17:51:35 -0800175 // 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.
Yi Jin4e843102018-02-14 15:36:18 -0800178 size_t reportByteSize = 0;
179 Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
180 mThrottler->addReportSize(reportByteSize);
Joe Onorato1754d742016-11-21 17:51:35 -0800181 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
182 unique_lock<mutex> lock(mLock);
183 schedule_send_backlog_to_dropbox_locked();
184 }
185}
186
Yi Jinb592e3b2018-02-01 15:17:04 -0800187void ReportHandler::send_backlog_to_dropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800188 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",
Yi Jinb592e3b2018-02-01 15:17:04 -0800193 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato1754d742016-11-21 17:51:35 -0800194 schedule_send_backlog_to_dropbox_locked();
195 } else {
196 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
197 }
198}
199
200// ================================================================================
201IncidentService::IncidentService(const sp<Looper>& handlerLooper)
Yi Jin4e843102018-02-14 15:36:18 -0800202 : mQueue(new ReportRequestQueue()),
203 mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
204 mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
Joe Onorato1754d742016-11-21 17:51:35 -0800205}
206
Yi Jinb592e3b2018-02-01 15:17:04 -0800207IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800208
Yi Jinb592e3b2018-02-01 15:17:04 -0800209Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato1754d742016-11-21 17:51:35 -0800210 ALOGI("reportIncident");
211
Yi Jin4bab3a12018-01-10 16:50:59 -0800212 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800213 if (!status.isOk()) {
214 return status;
215 }
216
217 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
218
219 return Status::ok();
220}
221
Yi Jinb592e3b2018-02-01 15:17:04 -0800222Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
223 const sp<IIncidentReportStatusListener>& listener,
224 const unique_fd& stream) {
Joe Onorato1754d742016-11-21 17:51:35 -0800225 ALOGI("reportIncidentToStream");
226
Yi Jin4bab3a12018-01-10 16:50:59 -0800227 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800228 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
Yi Jinb592e3b2018-02-01 15:17:04 -0800242Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800243 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
244 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800245 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800246 }
Yi Jinadd11e92017-07-30 16:10:07 -0700247
Joe Onorato1754d742016-11-21 17:51:35 -0800248 // When system_server is up and running, schedule the dropbox task to run.
249 mHandler->scheduleSendBacklogToDropbox();
250
251 return Status::ok();
252}
253
Yi Jinb592e3b2018-02-01 15:17:04 -0800254/**
255 * Implement our own because the default binder implementation isn't
256 * properly handling SHELL_COMMAND_TRANSACTION.
257 */
258status_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
306status_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 }
Yi Jin4e843102018-02-14 15:36:18 -0800313 if (!args[0].compare(String8("throttler"))) {
314 mThrottler->dump(out);
315 return NO_ERROR;
316 }
Yi Jin908c02f2018-06-22 16:51:40 -0700317 if (!args[0].compare(String8("section"))) {
318 int id = atoi(args[1]);
319 int idx = 0;
320 while (SECTION_LIST[idx] != NULL) {
321 const Section* section = SECTION_LIST[idx];
322 if (section->id == id) {
323 fprintf(out, "Section[%d] %s\n", id, section->name.string());
324 break;
325 }
326 idx++;
327 }
328 return NO_ERROR;
329 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800330 }
331 return cmd_help(out);
332}
333
334status_t IncidentService::cmd_help(FILE* out) {
335 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
336 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700337 fprintf(out, " Prints/parses for the section id.\n\n");
338 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
339 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800340 fprintf(out, "usage: adb shell cmd incident throttler\n");
341 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800342 return NO_ERROR;
343}
344
345static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
346 if (p == NULL) return;
347 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
348 if (p->children == NULL) return;
349 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
350 printPrivacy(p->children[i], out, indent + " ");
351 }
352}
353
354status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
355 const int argCount = args.size();
356 if (argCount >= 3) {
357 String8 opt = args[1];
358 int sectionId = atoi(args[2].string());
359
360 const Privacy* p = get_privacy_of_section(sectionId);
361 if (p == NULL) {
362 fprintf(err, "Can't find section id %d\n", sectionId);
363 return NO_ERROR;
364 }
365 fprintf(err, "Get privacy for %d\n", sectionId);
366 if (opt == "print") {
367 printPrivacy(p, out, String8(""));
368 } else if (opt == "parse") {
369 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700370 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800371 if (error != NO_ERROR) {
372 fprintf(err, "Error reading from stdin\n");
373 return error;
374 }
375 fprintf(err, "Read %zu bytes\n", buf.size());
Yi Jin86dce412018-03-07 11:36:57 -0800376 PrivacyBuffer pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800377
378 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
379 error = pBuf.strip(spec);
380 if (error != NO_ERROR) {
381 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
382 return error;
383 }
384 return pBuf.flush(fileno(out));
385 }
386 } else {
387 return cmd_help(out);
388 }
389 return NO_ERROR;
390}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700391
392} // namespace incidentd
393} // namespace os
394} // namespace android