blob: 1c3ebd8776950c2194a08c192375f4903a6b4296 [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 }
Bookatzda9b8d02018-11-14 13:14:45 -080085 break;
Yi Jin4bab3a12018-01-10 16:50:59 -080086 case DEST_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -080087 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
Bookatzda9b8d02018-11-14 13:14:45 -080088 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -080089 ALOGW("Calling pid %d and uid %d does not have permission to get explicit 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 explicit 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 }
Joe Onorato1754d742016-11-21 17:51:35 -080097 return Status::ok();
98}
Yi Jin6cacbcb2018-03-30 14:04:52 -070099
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 -0800103ReportRequestQueue::~ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800104
Yi Jinb592e3b2018-02-01 15:17:04 -0800105void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800106 unique_lock<mutex> lock(mLock);
107 mQueue.push_back(request);
108}
109
Yi Jinb592e3b2018-02-01 15:17:04 -0800110sp<ReportRequest> ReportRequestQueue::getNextRequest() {
Joe Onorato1754d742016-11-21 17:51:35 -0800111 unique_lock<mutex> lock(mLock);
112 if (mQueue.empty()) {
113 return NULL;
114 } else {
115 sp<ReportRequest> front(mQueue.front());
116 mQueue.pop_front();
117 return front;
118 }
119}
120
Joe Onorato1754d742016-11-21 17:51:35 -0800121// ================================================================================
Yi Jin4e843102018-02-14 15:36:18 -0800122ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
123 const sp<Throttler>& throttler)
124 : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
125 mHandlerLooper(handlerLooper),
126 mQueue(queue),
127 mThrottler(throttler) {}
Joe Onorato1754d742016-11-21 17:51:35 -0800128
Yi Jinb592e3b2018-02-01 15:17:04 -0800129ReportHandler::~ReportHandler() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800130
Yi Jinb592e3b2018-02-01 15:17:04 -0800131void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800132 switch (message.what) {
133 case WHAT_RUN_REPORT:
134 run_report();
135 break;
136 case WHAT_SEND_BACKLOG_TO_DROPBOX:
137 send_backlog_to_dropbox();
138 break;
139 }
140}
141
Yi Jinb592e3b2018-02-01 15:17:04 -0800142void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800143 mQueue->addRequest(request);
144 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
145 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
146}
147
Yi Jinb592e3b2018-02-01 15:17:04 -0800148void ReportHandler::scheduleSendBacklogToDropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800149 unique_lock<mutex> lock(mLock);
150 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
151 schedule_send_backlog_to_dropbox_locked();
152}
153
Yi Jinb592e3b2018-02-01 15:17:04 -0800154void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
Joe Onorato1754d742016-11-21 17:51:35 -0800155 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
Yi Jinb592e3b2018-02-01 15:17:04 -0800156 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
Joe Onorato1754d742016-11-21 17:51:35 -0800157}
158
Yi Jinb592e3b2018-02-01 15:17:04 -0800159void ReportHandler::run_report() {
Joe Onorato1754d742016-11-21 17:51:35 -0800160 sp<Reporter> reporter = new Reporter();
161
162 // Merge all of the requests into one that has all of the
163 // requested fields.
164 while (true) {
165 sp<ReportRequest> request = mQueue->getNextRequest();
166 if (request == NULL) {
167 break;
168 }
169 reporter->batch.add(request);
Joe Onorato1754d742016-11-21 17:51:35 -0800170 }
171
Yi Jin4e843102018-02-14 15:36:18 -0800172 if (mThrottler->shouldThrottle()) {
173 ALOGW("RunReport got throttled.");
174 return;
175 }
176
Joe Onorato1754d742016-11-21 17:51:35 -0800177 // Take the report, which might take a while. More requests might queue
178 // up while we're doing this, and we'll handle them in their next batch.
179 // TODO: We should further rate-limit the reports to no more than N per time-period.
Yi Jin4e843102018-02-14 15:36:18 -0800180 size_t reportByteSize = 0;
181 Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
182 mThrottler->addReportSize(reportByteSize);
Joe Onorato1754d742016-11-21 17:51:35 -0800183 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
184 unique_lock<mutex> lock(mLock);
185 schedule_send_backlog_to_dropbox_locked();
186 }
187}
188
Yi Jinb592e3b2018-02-01 15:17:04 -0800189void ReportHandler::send_backlog_to_dropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800190 if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
191 // There was a failure. Exponential backoff.
192 unique_lock<mutex> lock(mLock);
193 mBacklogDelay *= 2;
194 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800195 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato1754d742016-11-21 17:51:35 -0800196 schedule_send_backlog_to_dropbox_locked();
197 } else {
198 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
199 }
200}
201
202// ================================================================================
203IncidentService::IncidentService(const sp<Looper>& handlerLooper)
Yi Jin4e843102018-02-14 15:36:18 -0800204 : mQueue(new ReportRequestQueue()),
205 mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
206 mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
Joe Onorato1754d742016-11-21 17:51:35 -0800207}
208
Yi Jinb592e3b2018-02-01 15:17:04 -0800209IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800210
Yi Jinb592e3b2018-02-01 15:17:04 -0800211Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato1754d742016-11-21 17:51:35 -0800212 ALOGI("reportIncident");
213
Yi Jin4bab3a12018-01-10 16:50:59 -0800214 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800215 if (!status.isOk()) {
216 return status;
217 }
218
219 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
220
221 return Status::ok();
222}
223
Yi Jinb592e3b2018-02-01 15:17:04 -0800224Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
225 const sp<IIncidentReportStatusListener>& listener,
226 const unique_fd& stream) {
Joe Onorato1754d742016-11-21 17:51:35 -0800227 ALOGI("reportIncidentToStream");
228
Yi Jin4bab3a12018-01-10 16:50:59 -0800229 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800230 if (!status.isOk()) {
231 return status;
232 }
233
234 int fd = dup(stream.get());
235 if (fd < 0) {
236 return Status::fromStatusT(-errno);
237 }
238
239 mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
240
241 return Status::ok();
242}
243
Yi Jinb592e3b2018-02-01 15:17:04 -0800244Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800245 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
246 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800247 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800248 }
Yi Jinadd11e92017-07-30 16:10:07 -0700249
Joe Onorato1754d742016-11-21 17:51:35 -0800250 // When system_server is up and running, schedule the dropbox task to run.
251 mHandler->scheduleSendBacklogToDropbox();
252
253 return Status::ok();
254}
255
Yi Jinb592e3b2018-02-01 15:17:04 -0800256/**
257 * Implement our own because the default binder implementation isn't
258 * properly handling SHELL_COMMAND_TRANSACTION.
259 */
260status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
261 uint32_t flags) {
262 status_t err;
263
264 switch (code) {
265 case SHELL_COMMAND_TRANSACTION: {
266 int in = data.readFileDescriptor();
267 int out = data.readFileDescriptor();
268 int err = data.readFileDescriptor();
269 int argc = data.readInt32();
270 Vector<String8> args;
271 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
272 args.add(String8(data.readString16()));
273 }
274 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
275 sp<IResultReceiver> resultReceiver =
276 IResultReceiver::asInterface(data.readStrongBinder());
277
278 FILE* fin = fdopen(in, "r");
279 FILE* fout = fdopen(out, "w");
280 FILE* ferr = fdopen(err, "w");
281
282 if (fin == NULL || fout == NULL || ferr == NULL) {
283 resultReceiver->send(NO_MEMORY);
284 } else {
285 err = command(fin, fout, ferr, args);
286 resultReceiver->send(err);
287 }
288
289 if (fin != NULL) {
290 fflush(fin);
291 fclose(fin);
292 }
293 if (fout != NULL) {
294 fflush(fout);
295 fclose(fout);
296 }
297 if (fout != NULL) {
298 fflush(ferr);
299 fclose(ferr);
300 }
301
302 return NO_ERROR;
Bookatzda9b8d02018-11-14 13:14:45 -0800303 } break;
Yi Jinb592e3b2018-02-01 15:17:04 -0800304 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
305 }
306}
307
308status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
309 const int argCount = args.size();
310
311 if (argCount >= 1) {
312 if (!args[0].compare(String8("privacy"))) {
313 return cmd_privacy(in, out, err, args);
314 }
Yi Jin4e843102018-02-14 15:36:18 -0800315 if (!args[0].compare(String8("throttler"))) {
316 mThrottler->dump(out);
317 return NO_ERROR;
318 }
Yi Jin908c02f2018-06-22 16:51:40 -0700319 if (!args[0].compare(String8("section"))) {
320 int id = atoi(args[1]);
321 int idx = 0;
322 while (SECTION_LIST[idx] != NULL) {
323 const Section* section = SECTION_LIST[idx];
324 if (section->id == id) {
325 fprintf(out, "Section[%d] %s\n", id, section->name.string());
326 break;
327 }
328 idx++;
329 }
330 return NO_ERROR;
331 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800332 }
333 return cmd_help(out);
334}
335
336status_t IncidentService::cmd_help(FILE* out) {
337 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
338 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700339 fprintf(out, " Prints/parses for the section id.\n\n");
340 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
341 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800342 fprintf(out, "usage: adb shell cmd incident throttler\n");
343 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800344 return NO_ERROR;
345}
346
347static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
348 if (p == NULL) return;
349 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
350 if (p->children == NULL) return;
351 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
352 printPrivacy(p->children[i], out, indent + " ");
353 }
354}
355
356status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
357 const int argCount = args.size();
358 if (argCount >= 3) {
359 String8 opt = args[1];
360 int sectionId = atoi(args[2].string());
361
362 const Privacy* p = get_privacy_of_section(sectionId);
363 if (p == NULL) {
364 fprintf(err, "Can't find section id %d\n", sectionId);
365 return NO_ERROR;
366 }
367 fprintf(err, "Get privacy for %d\n", sectionId);
368 if (opt == "print") {
369 printPrivacy(p, out, String8(""));
370 } else if (opt == "parse") {
371 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700372 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800373 if (error != NO_ERROR) {
374 fprintf(err, "Error reading from stdin\n");
375 return error;
376 }
377 fprintf(err, "Read %zu bytes\n", buf.size());
Yi Jin86dce412018-03-07 11:36:57 -0800378 PrivacyBuffer pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800379
380 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
381 error = pBuf.strip(spec);
382 if (error != NO_ERROR) {
383 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
384 return error;
385 }
386 return pBuf.flush(fileno(out));
387 }
388 } else {
389 return cmd_help(out);
390 }
391 return NO_ERROR;
392}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700393
394} // namespace incidentd
395} // namespace os
396} // namespace android