blob: 9ae624094dcabea27bcb24e018d60078c88b9fdb [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 Jinb592e3b2018-02-01 15:17:04 -080016#include "Log.h"
Joe Onorato1754d742016-11-21 17:51:35 -080017
18#include "IncidentService.h"
19
Yi Jinb592e3b2018-02-01 15:17:04 -080020#include "FdBuffer.h"
21#include "PrivacyBuffer.h"
Joe Onorato1754d742016-11-21 17:51:35 -080022#include "Reporter.h"
Yi Jinb592e3b2018-02-01 15:17:04 -080023#include "incidentd_util.h"
24#include "section_list.h"
Joe Onorato1754d742016-11-21 17:51:35 -080025
26#include <binder/IPCThreadState.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080027#include <binder/IResultReceiver.h>
Joe Onorato1754d742016-11-21 17:51:35 -080028#include <binder/IServiceManager.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080029#include <binder/IShellCallback.h>
Joe Onorato1754d742016-11-21 17:51:35 -080030#include <cutils/log.h>
31#include <private/android_filesystem_config.h>
32#include <utils/Looper.h>
33
34#include <unistd.h>
35
36using namespace android;
Yi Jinb592e3b2018-02-01 15:17:04 -080037using namespace android::base;
Joe Onorato1754d742016-11-21 17:51:35 -080038
Yi Jinb592e3b2018-02-01 15:17:04 -080039enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
Joe Onorato1754d742016-11-21 17:51:35 -080040
41//#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL * 60 * 5)
42#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
43
44// ================================================================================
45String16 const DUMP_PERMISSION("android.permission.DUMP");
46String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
47
Yi Jinb592e3b2018-02-01 15:17:04 -080048static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080049 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080050 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080051 if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
52 // root doesn't have permission.DUMP if don't do this!
53 return Status::ok();
54 }
55
Yi Jin4bab3a12018-01-10 16:50:59 -080056 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080057 if (!checkCallingPermission(DUMP_PERMISSION)) {
58 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080059 callingPid, callingUid);
60 return Status::fromExceptionCode(
61 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080062 "Calling process does not have permission: android.permission.DUMP");
63 }
64 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
65 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
Yi Jinb592e3b2018-02-01 15:17:04 -080066 callingPid, callingUid);
67 return Status::fromExceptionCode(
68 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080069 "Calling process does not have permission: android.permission.USAGE_STATS");
70 }
Yi Jin4bab3a12018-01-10 16:50:59 -080071
72 // checking calling request uid permission.
Yi Jin4bab3a12018-01-10 16:50:59 -080073 switch (args.dest()) {
74 case DEST_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080075 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
76 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080077 callingPid, callingUid);
78 return Status::fromExceptionCode(
79 Status::EX_SECURITY,
80 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -080081 }
82 case DEST_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -080083 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
84 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -080085 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080086 callingPid, callingUid);
87 return Status::fromExceptionCode(
88 Status::EX_SECURITY,
89 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -080090 }
91 }
Joe Onorato1754d742016-11-21 17:51:35 -080092 return Status::ok();
93}
Joe Onorato1754d742016-11-21 17:51:35 -080094// ================================================================================
Yi Jinb592e3b2018-02-01 15:17:04 -080095ReportRequestQueue::ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -080096
Yi Jinb592e3b2018-02-01 15:17:04 -080097ReportRequestQueue::~ReportRequestQueue() {}
Joe Onorato1754d742016-11-21 17:51:35 -080098
Yi Jinb592e3b2018-02-01 15:17:04 -080099void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800100 unique_lock<mutex> lock(mLock);
101 mQueue.push_back(request);
102}
103
Yi Jinb592e3b2018-02-01 15:17:04 -0800104sp<ReportRequest> ReportRequestQueue::getNextRequest() {
Joe Onorato1754d742016-11-21 17:51:35 -0800105 unique_lock<mutex> lock(mLock);
106 if (mQueue.empty()) {
107 return NULL;
108 } else {
109 sp<ReportRequest> front(mQueue.front());
110 mQueue.pop_front();
111 return front;
112 }
113}
114
Joe Onorato1754d742016-11-21 17:51:35 -0800115// ================================================================================
116ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue)
Yi Jinb592e3b2018-02-01 15:17:04 -0800117 : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS), mHandlerLooper(handlerLooper), mQueue(queue) {}
Joe Onorato1754d742016-11-21 17:51:35 -0800118
Yi Jinb592e3b2018-02-01 15:17:04 -0800119ReportHandler::~ReportHandler() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800120
Yi Jinb592e3b2018-02-01 15:17:04 -0800121void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800122 switch (message.what) {
123 case WHAT_RUN_REPORT:
124 run_report();
125 break;
126 case WHAT_SEND_BACKLOG_TO_DROPBOX:
127 send_backlog_to_dropbox();
128 break;
129 }
130}
131
Yi Jinb592e3b2018-02-01 15:17:04 -0800132void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
Joe Onorato1754d742016-11-21 17:51:35 -0800133 mQueue->addRequest(request);
134 mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
135 mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
136}
137
Yi Jinb592e3b2018-02-01 15:17:04 -0800138void ReportHandler::scheduleSendBacklogToDropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800139 unique_lock<mutex> lock(mLock);
140 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
141 schedule_send_backlog_to_dropbox_locked();
142}
143
Yi Jinb592e3b2018-02-01 15:17:04 -0800144void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
Joe Onorato1754d742016-11-21 17:51:35 -0800145 mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
Yi Jinb592e3b2018-02-01 15:17:04 -0800146 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
Joe Onorato1754d742016-11-21 17:51:35 -0800147}
148
Yi Jinb592e3b2018-02-01 15:17:04 -0800149void ReportHandler::run_report() {
Joe Onorato1754d742016-11-21 17:51:35 -0800150 sp<Reporter> reporter = new Reporter();
151
152 // Merge all of the requests into one that has all of the
153 // requested fields.
154 while (true) {
155 sp<ReportRequest> request = mQueue->getNextRequest();
156 if (request == NULL) {
157 break;
158 }
159 reporter->batch.add(request);
Joe Onorato1754d742016-11-21 17:51:35 -0800160 }
161
162 // Take the report, which might take a while. More requests might queue
163 // up while we're doing this, and we'll handle them in their next batch.
164 // TODO: We should further rate-limit the reports to no more than N per time-period.
165 Reporter::run_report_status_t reportStatus = reporter->runReport();
166 if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
167 unique_lock<mutex> lock(mLock);
168 schedule_send_backlog_to_dropbox_locked();
169 }
170}
171
Yi Jinb592e3b2018-02-01 15:17:04 -0800172void ReportHandler::send_backlog_to_dropbox() {
Joe Onorato1754d742016-11-21 17:51:35 -0800173 if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
174 // There was a failure. Exponential backoff.
175 unique_lock<mutex> lock(mLock);
176 mBacklogDelay *= 2;
177 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800178 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato1754d742016-11-21 17:51:35 -0800179 schedule_send_backlog_to_dropbox_locked();
180 } else {
181 mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
182 }
183}
184
185// ================================================================================
186IncidentService::IncidentService(const sp<Looper>& handlerLooper)
Yi Jinb592e3b2018-02-01 15:17:04 -0800187 : mQueue(new ReportRequestQueue()) {
Joe Onorato1754d742016-11-21 17:51:35 -0800188 mHandler = new ReportHandler(handlerLooper, mQueue);
189}
190
Yi Jinb592e3b2018-02-01 15:17:04 -0800191IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800192
Yi Jinb592e3b2018-02-01 15:17:04 -0800193Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato1754d742016-11-21 17:51:35 -0800194 ALOGI("reportIncident");
195
Yi Jin4bab3a12018-01-10 16:50:59 -0800196 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800197 if (!status.isOk()) {
198 return status;
199 }
200
201 mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
202
203 return Status::ok();
204}
205
Yi Jinb592e3b2018-02-01 15:17:04 -0800206Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
207 const sp<IIncidentReportStatusListener>& listener,
208 const unique_fd& stream) {
Joe Onorato1754d742016-11-21 17:51:35 -0800209 ALOGI("reportIncidentToStream");
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 int fd = dup(stream.get());
217 if (fd < 0) {
218 return Status::fromStatusT(-errno);
219 }
220
221 mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
222
223 return Status::ok();
224}
225
Yi Jinb592e3b2018-02-01 15:17:04 -0800226Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800227 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
228 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800229 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800230 }
Yi Jinadd11e92017-07-30 16:10:07 -0700231
Joe Onorato1754d742016-11-21 17:51:35 -0800232 // When system_server is up and running, schedule the dropbox task to run.
233 mHandler->scheduleSendBacklogToDropbox();
234
235 return Status::ok();
236}
237
Yi Jinb592e3b2018-02-01 15:17:04 -0800238/**
239 * Implement our own because the default binder implementation isn't
240 * properly handling SHELL_COMMAND_TRANSACTION.
241 */
242status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
243 uint32_t flags) {
244 status_t err;
245
246 switch (code) {
247 case SHELL_COMMAND_TRANSACTION: {
248 int in = data.readFileDescriptor();
249 int out = data.readFileDescriptor();
250 int err = data.readFileDescriptor();
251 int argc = data.readInt32();
252 Vector<String8> args;
253 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
254 args.add(String8(data.readString16()));
255 }
256 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
257 sp<IResultReceiver> resultReceiver =
258 IResultReceiver::asInterface(data.readStrongBinder());
259
260 FILE* fin = fdopen(in, "r");
261 FILE* fout = fdopen(out, "w");
262 FILE* ferr = fdopen(err, "w");
263
264 if (fin == NULL || fout == NULL || ferr == NULL) {
265 resultReceiver->send(NO_MEMORY);
266 } else {
267 err = command(fin, fout, ferr, args);
268 resultReceiver->send(err);
269 }
270
271 if (fin != NULL) {
272 fflush(fin);
273 fclose(fin);
274 }
275 if (fout != NULL) {
276 fflush(fout);
277 fclose(fout);
278 }
279 if (fout != NULL) {
280 fflush(ferr);
281 fclose(ferr);
282 }
283
284 return NO_ERROR;
285 }
286 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
287 }
288}
289
290status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
291 const int argCount = args.size();
292
293 if (argCount >= 1) {
294 if (!args[0].compare(String8("privacy"))) {
295 return cmd_privacy(in, out, err, args);
296 }
297 }
298 return cmd_help(out);
299}
300
301status_t IncidentService::cmd_help(FILE* out) {
302 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
303 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
304 fprintf(out, " Prints/parses for the section id.\n");
305 return NO_ERROR;
306}
307
308static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
309 if (p == NULL) return;
310 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
311 if (p->children == NULL) return;
312 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
313 printPrivacy(p->children[i], out, indent + " ");
314 }
315}
316
317status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
318 const int argCount = args.size();
319 if (argCount >= 3) {
320 String8 opt = args[1];
321 int sectionId = atoi(args[2].string());
322
323 const Privacy* p = get_privacy_of_section(sectionId);
324 if (p == NULL) {
325 fprintf(err, "Can't find section id %d\n", sectionId);
326 return NO_ERROR;
327 }
328 fprintf(err, "Get privacy for %d\n", sectionId);
329 if (opt == "print") {
330 printPrivacy(p, out, String8(""));
331 } else if (opt == "parse") {
332 FdBuffer buf;
333 status_t error = buf.read(fileno(in), 60000);
334 if (error != NO_ERROR) {
335 fprintf(err, "Error reading from stdin\n");
336 return error;
337 }
338 fprintf(err, "Read %zu bytes\n", buf.size());
339 auto data = buf.data();
340 PrivacyBuffer pBuf(p, data);
341
342 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
343 error = pBuf.strip(spec);
344 if (error != NO_ERROR) {
345 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
346 return error;
347 }
348 return pBuf.flush(fileno(out));
349 }
350 } else {
351 return cmd_help(out);
352 }
353 return NO_ERROR;
354}