blob: 6c2b8551bf73999dda108e7d8988661257ab48ee [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"
Joe Onorato99598ee2019-02-11 15:55:13 +000022#include "PrivacyFilter.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>
Yao Chencbafce92019-04-01 15:56:44 -070035#include <thread>
Joe Onorato1754d742016-11-21 17:51:35 -080036
37#include <unistd.h>
38
Joe Onorato99598ee2019-02-11 15:55:13 +000039enum {
40 WHAT_TAKE_REPORT = 1,
41 WHAT_SEND_BROADCASTS = 2
42};
Joe Onorato1754d742016-11-21 17:51:35 -080043
Joe Onorato99598ee2019-02-11 15:55:13 +000044#define DEFAULT_DELAY_NS (1000000000LL)
Joe Onorato1754d742016-11-21 17:51:35 -080045
Yao Chen31829672019-05-23 10:43:47 -070046#define DEFAULT_BYTES_SIZE_LIMIT (96 * 1024 * 1024) // 96MB
Yi Jin4e843102018-02-14 15:36:18 -080047#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
48
Mike Ma5a57d792019-08-21 14:52:46 -070049// Skip these sections (for dumpstate only)
Mike Ma28381692018-12-04 15:46:29 -080050// Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report.
Mike Ma5a57d792019-08-21 14:52:46 -070051#define SKIPPED_DUMPSTATE_SECTIONS { \
52 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
53 1200, 1201, 1202, /* Native, hal, java traces */ }
Mike Ma85434ec2018-11-27 10:32:31 -080054
Yi Jin6cacbcb2018-03-30 14:04:52 -070055namespace android {
56namespace os {
57namespace incidentd {
58
Joe Onorato99598ee2019-02-11 15:55:13 +000059String16 const APPROVE_INCIDENT_REPORTS("android.permission.APPROVE_INCIDENT_REPORTS");
Joe Onorato1754d742016-11-21 17:51:35 -080060String16 const DUMP_PERMISSION("android.permission.DUMP");
61String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
62
Yi Jinb592e3b2018-02-01 15:17:04 -080063static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080064 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080065 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080066 if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
Joe Onorato99598ee2019-02-11 15:55:13 +000067 // Root and shell are ok.
68 return Status::ok();
69 }
70
71 if (checkCallingPermission(APPROVE_INCIDENT_REPORTS)) {
72 // Permission controller (this is a singleton permission that is always granted
73 // exactly for PermissionController) is allowed to access incident reports
74 // so it can show the user info about what they are approving.
Yi Jin437aa6e2018-01-10 11:34:26 -080075 return Status::ok();
76 }
77
Yi Jin4bab3a12018-01-10 16:50:59 -080078 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080079 if (!checkCallingPermission(DUMP_PERMISSION)) {
80 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080081 callingPid, callingUid);
82 return Status::fromExceptionCode(
83 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080084 "Calling process does not have permission: android.permission.DUMP");
85 }
86 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
87 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
Yi Jinb592e3b2018-02-01 15:17:04 -080088 callingPid, callingUid);
89 return Status::fromExceptionCode(
90 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080091 "Calling process does not have permission: android.permission.USAGE_STATS");
92 }
Yi Jin4bab3a12018-01-10 16:50:59 -080093
94 // checking calling request uid permission.
Joe Onorato99598ee2019-02-11 15:55:13 +000095 switch (args.getPrivacyPolicy()) {
96 case PRIVACY_POLICY_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080097 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
98 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -080099 callingPid, callingUid);
100 return Status::fromExceptionCode(
101 Status::EX_SECURITY,
102 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800103 }
Bookatzda9b8d02018-11-14 13:14:45 -0800104 break;
Joe Onorato99598ee2019-02-11 15:55:13 +0000105 case PRIVACY_POLICY_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -0800106 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
Bookatzda9b8d02018-11-14 13:14:45 -0800107 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -0800108 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -0800109 callingPid, callingUid);
110 return Status::fromExceptionCode(
111 Status::EX_SECURITY,
112 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800113 }
Bookatzda9b8d02018-11-14 13:14:45 -0800114 break;
Yi Jin4bab3a12018-01-10 16:50:59 -0800115 }
Joe Onorato1754d742016-11-21 17:51:35 -0800116 return Status::ok();
117}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700118
Joe Onorato99598ee2019-02-11 15:55:13 +0000119static string build_uri(const string& pkg, const string& cls, const string& id) {
Yao Chencbafce92019-04-01 15:56:44 -0700120 return "content://android.os.IncidentManager/pending?pkg="
121 + pkg + "&receiver=" + cls + "&r=" + id;
Joe Onorato1754d742016-11-21 17:51:35 -0800122}
123
Joe Onorato1754d742016-11-21 17:51:35 -0800124// ================================================================================
Joe Onorato99598ee2019-02-11 15:55:13 +0000125ReportHandler::ReportHandler(const sp<WorkDirectory>& workDirectory,
Mike Ma643de922019-12-17 10:56:17 -0800126 const sp<Broadcaster>& broadcaster,
127 const sp<Looper>& handlerLooper,
128 const sp<Throttler>& throttler,
129 const vector<BringYourOwnSection*>& registeredSections)
Joe Onorato99598ee2019-02-11 15:55:13 +0000130 :mLock(),
131 mWorkDirectory(workDirectory),
132 mBroadcaster(broadcaster),
133 mHandlerLooper(handlerLooper),
134 mBacklogDelay(DEFAULT_DELAY_NS),
135 mThrottler(throttler),
Mike Ma643de922019-12-17 10:56:17 -0800136 mRegisteredSections(registeredSections),
Joe Onorato99598ee2019-02-11 15:55:13 +0000137 mBatch(new ReportBatch()) {
138}
Joe Onorato1754d742016-11-21 17:51:35 -0800139
Joe Onorato99598ee2019-02-11 15:55:13 +0000140ReportHandler::~ReportHandler() {
141}
Joe Onorato1754d742016-11-21 17:51:35 -0800142
Yi Jinb592e3b2018-02-01 15:17:04 -0800143void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800144 switch (message.what) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000145 case WHAT_TAKE_REPORT:
146 take_report();
Joe Onorato1754d742016-11-21 17:51:35 -0800147 break;
Joe Onorato99598ee2019-02-11 15:55:13 +0000148 case WHAT_SEND_BROADCASTS:
149 send_broadcasts();
Joe Onorato1754d742016-11-21 17:51:35 -0800150 break;
151 }
152}
153
Joe Onorato99598ee2019-02-11 15:55:13 +0000154void ReportHandler::schedulePersistedReport(const IncidentReportArgs& args) {
155 mBatch->addPersistedReport(args);
156 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
157 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
Joe Onorato1754d742016-11-21 17:51:35 -0800158}
159
Joe Onorato99598ee2019-02-11 15:55:13 +0000160void ReportHandler::scheduleStreamingReport(const IncidentReportArgs& args,
161 const sp<IIncidentReportStatusListener>& listener, int streamFd) {
162 mBatch->addStreamingReport(args, listener, streamFd);
163 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
164 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
165}
166
167void ReportHandler::scheduleSendBacklog() {
Joe Onorato1754d742016-11-21 17:51:35 -0800168 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000169 mBacklogDelay = DEFAULT_DELAY_NS;
170 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800171}
172
Joe Onorato99598ee2019-02-11 15:55:13 +0000173void ReportHandler::schedule_send_broadcasts_locked() {
174 mHandlerLooper->removeMessages(this, WHAT_SEND_BROADCASTS);
175 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BROADCASTS));
Joe Onorato1754d742016-11-21 17:51:35 -0800176}
177
Joe Onorato99598ee2019-02-11 15:55:13 +0000178void ReportHandler::take_report() {
Joe Onoratoe5472052019-04-24 16:27:33 -0700179 // Cycle the batch and throttle.
Joe Onorato99598ee2019-02-11 15:55:13 +0000180 sp<ReportBatch> batch;
181 {
182 unique_lock<mutex> lock(mLock);
Joe Onoratoe5472052019-04-24 16:27:33 -0700183 batch = mThrottler->filterBatch(mBatch);
Joe Onorato1754d742016-11-21 17:51:35 -0800184 }
185
Joe Onorato99598ee2019-02-11 15:55:13 +0000186 if (batch->empty()) {
187 // Nothing to do.
188 return;
189 }
190
Mike Ma643de922019-12-17 10:56:17 -0800191 sp<Reporter> reporter = new Reporter(mWorkDirectory, batch, mRegisteredSections);
Joe Onorato99598ee2019-02-11 15:55:13 +0000192
Joe Onorato1754d742016-11-21 17:51:35 -0800193 // Take the report, which might take a while. More requests might queue
194 // up while we're doing this, and we'll handle them in their next batch.
195 // TODO: We should further rate-limit the reports to no more than N per time-period.
Joe Onorato99598ee2019-02-11 15:55:13 +0000196 // TODO: Move this inside reporter.
Yi Jin4e843102018-02-14 15:36:18 -0800197 size_t reportByteSize = 0;
Joe Onorato99598ee2019-02-11 15:55:13 +0000198 reporter->runReport(&reportByteSize);
199
Joe Onoratoe5472052019-04-24 16:27:33 -0700200 // Tell the throttler how big it was, for the next throttling.
201 // TODO: This still isn't ideal. The throttler really should just track the
202 // persisted reqeusts, but changing Reporter::runReport() to track that individually
203 // will be a big change.
204 if (batch->hasPersistedReports()) {
205 mThrottler->addReportSize(reportByteSize);
206 }
Joe Onorato99598ee2019-02-11 15:55:13 +0000207
208 // Kick off the next steps, one of which is to send any new or otherwise remaining
209 // approvals, and one of which is to send any new or remaining broadcasts.
210 {
Joe Onorato1754d742016-11-21 17:51:35 -0800211 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000212 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800213 }
214}
215
Joe Onorato99598ee2019-02-11 15:55:13 +0000216void ReportHandler::send_broadcasts() {
217 Broadcaster::broadcast_status_t result = mBroadcaster->sendBroadcasts();
218 if (result == Broadcaster::BROADCASTS_FINISHED) {
219 // We're done.
220 unique_lock<mutex> lock(mLock);
221 mBacklogDelay = DEFAULT_DELAY_NS;
222 } else if (result == Broadcaster::BROADCASTS_REPEAT) {
223 // It worked, but there are more.
224 unique_lock<mutex> lock(mLock);
225 mBacklogDelay = DEFAULT_DELAY_NS;
226 schedule_send_broadcasts_locked();
227 } else if (result == Broadcaster::BROADCASTS_BACKOFF) {
Joe Onorato1754d742016-11-21 17:51:35 -0800228 // There was a failure. Exponential backoff.
229 unique_lock<mutex> lock(mLock);
230 mBacklogDelay *= 2;
231 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800232 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato99598ee2019-02-11 15:55:13 +0000233 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800234 }
235}
236
237// ================================================================================
Joe Onorato99598ee2019-02-11 15:55:13 +0000238IncidentService::IncidentService(const sp<Looper>& handlerLooper) {
239 mThrottler = new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS);
240 mWorkDirectory = new WorkDirectory();
241 mBroadcaster = new Broadcaster(mWorkDirectory);
242 mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper,
Mike Ma643de922019-12-17 10:56:17 -0800243 mThrottler, mRegisteredSections);
Joe Onorato99598ee2019-02-11 15:55:13 +0000244 mBroadcaster->setHandler(mHandler);
Joe Onorato1754d742016-11-21 17:51:35 -0800245}
246
Yi Jinb592e3b2018-02-01 15:17:04 -0800247IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800248
Yi Jinb592e3b2018-02-01 15:17:04 -0800249Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onoratoe5472052019-04-24 16:27:33 -0700250 IncidentReportArgs argsCopy(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800251
Joe Onoratoe5472052019-04-24 16:27:33 -0700252 // Validate that the privacy policy is one of the real ones.
253 // If it isn't, clamp it to the next more restrictive real one.
254 argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy()));
Joe Onorato99598ee2019-02-11 15:55:13 +0000255
256 // TODO: Check that the broadcast recevier has the proper permissions
257 // TODO: Maybe we should consider relaxing the permissions if it's going to
258 // dropbox, but definitely not if it's going to the broadcaster.
Yi Jin4bab3a12018-01-10 16:50:59 -0800259 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800260 if (!status.isOk()) {
261 return status;
262 }
263
Joe Onoratoe5472052019-04-24 16:27:33 -0700264 // If they asked for the LOCAL privacy policy, give them EXPLICT. LOCAL has to
265 // be streamed. (This only applies to shell/root, because everyone else would have
266 // been rejected by checkIncidentPermissions()).
267 if (argsCopy.getPrivacyPolicy() < PRIVACY_POLICY_EXPLICIT) {
268 ALOGI("Demoting privacy policy to EXPLICT for persisted report.");
269 argsCopy.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
270 }
271
Joe Onorato99598ee2019-02-11 15:55:13 +0000272 // If they didn't specify a component, use dropbox.
Joe Onorato99598ee2019-02-11 15:55:13 +0000273 if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) {
274 argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName());
275 argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName());
276 }
277
278 mHandler->schedulePersistedReport(argsCopy);
Joe Onorato1754d742016-11-21 17:51:35 -0800279
280 return Status::ok();
281}
282
Yi Jinb592e3b2018-02-01 15:17:04 -0800283Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
284 const sp<IIncidentReportStatusListener>& listener,
Jiyong Parkb8ba2342019-11-25 11:03:38 +0900285 unique_fd stream) {
Joe Onoratoe5472052019-04-24 16:27:33 -0700286 IncidentReportArgs argsCopy(args);
Joe Onorato99598ee2019-02-11 15:55:13 +0000287
288 // Streaming reports can not also be broadcast.
Joe Onorato99598ee2019-02-11 15:55:13 +0000289 argsCopy.setReceiverPkg("");
290 argsCopy.setReceiverCls("");
291
Joe Onoratoe5472052019-04-24 16:27:33 -0700292 // Validate that the privacy policy is one of the real ones.
293 // If it isn't, clamp it to the next more restrictive real one.
294 argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy()));
295
Joe Onorato99598ee2019-02-11 15:55:13 +0000296 Status status = checkIncidentPermissions(argsCopy);
Joe Onorato1754d742016-11-21 17:51:35 -0800297 if (!status.isOk()) {
298 return status;
299 }
300
Joe Onorato99598ee2019-02-11 15:55:13 +0000301 // The ReportRequest takes ownership of the fd, so we need to dup it.
Joe Onorato1754d742016-11-21 17:51:35 -0800302 int fd = dup(stream.get());
303 if (fd < 0) {
304 return Status::fromStatusT(-errno);
305 }
306
Joe Onorato99598ee2019-02-11 15:55:13 +0000307 mHandler->scheduleStreamingReport(argsCopy, listener, fd);
Joe Onorato1754d742016-11-21 17:51:35 -0800308
309 return Status::ok();
310}
311
Jiyong Parkb8ba2342019-11-25 11:03:38 +0900312Status IncidentService::reportIncidentToDumpstate(unique_fd stream,
Mike Ma5a57d792019-08-21 14:52:46 -0700313 const sp<IIncidentReportStatusListener>& listener) {
314 uid_t caller = IPCThreadState::self()->getCallingUid();
315 if (caller != AID_ROOT && caller != AID_SHELL) {
316 ALOGW("Calling uid %d does not have permission: only ROOT or SHELL allowed", caller);
317 return Status::fromExceptionCode(Status::EX_SECURITY, "Only ROOT or SHELL allowed");
318 }
319
320 ALOGD("Stream incident report to dumpstate");
321 IncidentReportArgs incidentArgs;
322 // Privacy policy for dumpstate incident reports is always EXPLICIT.
323 incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
324
325 int skipped[] = SKIPPED_DUMPSTATE_SECTIONS;
326 for (const Section** section = SECTION_LIST; *section; section++) {
327 const int id = (*section)->id;
328 if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)
329 && !section_requires_specific_mention(id)) {
330 incidentArgs.addSection(id);
331 }
332 }
Mike Ma643de922019-12-17 10:56:17 -0800333 for (const Section* section : mRegisteredSections) {
334 if (!section_requires_specific_mention(section->id)) {
335 incidentArgs.addSection(section->id);
336 }
337 }
Mike Ma5a57d792019-08-21 14:52:46 -0700338
339 // The ReportRequest takes ownership of the fd, so we need to dup it.
340 int fd = dup(stream.get());
341 if (fd < 0) {
342 return Status::fromStatusT(-errno);
343 }
344
345 mHandler->scheduleStreamingReport(incidentArgs, listener, fd);
346
347 return Status::ok();
348}
349
Mike Ma643de922019-12-17 10:56:17 -0800350Status IncidentService::registerSection(const int id, const String16& name16,
351 const sp<IIncidentDumpCallback>& callback) {
352 const char* name = String8(name16).c_str();
Mike Mac2ab45a2020-01-17 06:11:24 +0000353 const uid_t callingUid = IPCThreadState::self()->getCallingUid();
354 ALOGI("Uid %d registers section %d '%s'", callingUid, id, name);
Mike Ma643de922019-12-17 10:56:17 -0800355 if (callback == nullptr) {
356 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
357 }
Mike Ma643de922019-12-17 10:56:17 -0800358 for (int i = 0; i < mRegisteredSections.size(); i++) {
359 if (mRegisteredSections.at(i)->id == id) {
360 if (mRegisteredSections.at(i)->uid != callingUid) {
361 ALOGW("Error registering section %d: calling uid does not match", id);
362 return Status::fromExceptionCode(Status::EX_SECURITY);
363 }
364 mRegisteredSections.at(i) = new BringYourOwnSection(id, name, callingUid, callback);
365 return Status::ok();
366 }
367 }
368 mRegisteredSections.push_back(new BringYourOwnSection(id, name, callingUid, callback));
369 return Status::ok();
370}
371
372Status IncidentService::unregisterSection(const int id) {
Mike Ma643de922019-12-17 10:56:17 -0800373 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Mike Mac2ab45a2020-01-17 06:11:24 +0000374 ALOGI("Uid %d unregisters section %d", callingUid, id);
375
Mike Ma643de922019-12-17 10:56:17 -0800376 for (auto it = mRegisteredSections.begin(); it != mRegisteredSections.end(); it++) {
377 if ((*it)->id == id) {
378 if ((*it)->uid != callingUid) {
379 ALOGW("Error unregistering section %d: calling uid does not match", id);
380 return Status::fromExceptionCode(Status::EX_SECURITY);
381 }
382 mRegisteredSections.erase(it);
383 return Status::ok();
384 }
385 }
386 ALOGW("Section %d not found", id);
387 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
388}
389
Yi Jinb592e3b2018-02-01 15:17:04 -0800390Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800391 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
392 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800393 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800394 }
Yi Jinadd11e92017-07-30 16:10:07 -0700395
Joe Onorato1754d742016-11-21 17:51:35 -0800396 // When system_server is up and running, schedule the dropbox task to run.
Joe Onorato99598ee2019-02-11 15:55:13 +0000397 mBroadcaster->reset();
398 mHandler->scheduleSendBacklog();
399
400 return Status::ok();
401}
402
403Status IncidentService::getIncidentReportList(const String16& pkg16, const String16& cls16,
404 vector<String16>* result) {
405 status_t err;
406 const string pkg(String8(pkg16).string());
407 const string cls(String8(cls16).string());
408
409 // List the reports
410 vector<sp<ReportFile>> all;
411 err = mWorkDirectory->getReports(&all, 0);
412 if (err != NO_ERROR) {
413 return Status::fromStatusT(err);
414 }
415
416 // Find the ones that match pkg and cls.
417 for (sp<ReportFile>& file: all) {
418 err = file->loadEnvelope();
419 if (err != NO_ERROR) {
420 continue;
421 }
422 const ReportFileProto& envelope = file->getEnvelope();
423 size_t reportCount = envelope.report_size();
424 for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
425 const ReportFileProto_Report& report = envelope.report(reportIndex);
426 if (pkg == report.pkg() && cls == report.cls()) {
427 result->push_back(String16(build_uri(pkg, cls, file->getId()).c_str()));
428 break;
429 }
430 }
431 }
432
433 return Status::ok();
434}
435
436Status IncidentService::getIncidentReport(const String16& pkg16, const String16& cls16,
437 const String16& id16, IncidentManager::IncidentReport* result) {
438 status_t err;
439
440 const string pkg(String8(pkg16).string());
441 const string cls(String8(cls16).string());
442 const string id(String8(id16).string());
443
444 IncidentReportArgs args;
445 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, &args);
446 if (file != nullptr) {
Yao Chencbafce92019-04-01 15:56:44 -0700447 // Create pipe
448 int fds[2];
449 if (pipe(fds) != 0) {
450 ALOGW("Error opening pipe to filter incident report: %s",
451 file->getDataFileName().c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000452 return Status::ok();
453 }
Joe Onorato99598ee2019-02-11 15:55:13 +0000454 result->setTimestampNs(file->getTimestampNs());
455 result->setPrivacyPolicy(file->getEnvelope().privacy_policy());
Yao Chencbafce92019-04-01 15:56:44 -0700456 result->takeFileDescriptor(fds[0]);
457 int writeFd = fds[1];
458 // spawn a thread to write the data. Release the writeFd ownership to the thread.
459 thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); });
460
461 th.detach();
Joe Onorato99598ee2019-02-11 15:55:13 +0000462 }
463
464 return Status::ok();
465}
466
467Status IncidentService::deleteIncidentReports(const String16& pkg16, const String16& cls16,
468 const String16& id16) {
469 const string pkg(String8(pkg16).string());
470 const string cls(String8(cls16).string());
471 const string id(String8(id16).string());
472
473 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, nullptr);
474 if (file != nullptr) {
475 mWorkDirectory->commit(file, pkg, cls);
476 }
477 mBroadcaster->clearBroadcasts(pkg, cls, id);
478
479 return Status::ok();
480}
481
482Status IncidentService::deleteAllIncidentReports(const String16& pkg16) {
483 const string pkg(String8(pkg16).string());
484
485 mWorkDirectory->commitAll(pkg);
486 mBroadcaster->clearPackageBroadcasts(pkg);
Joe Onorato1754d742016-11-21 17:51:35 -0800487
488 return Status::ok();
489}
490
Yi Jinb592e3b2018-02-01 15:17:04 -0800491/**
492 * Implement our own because the default binder implementation isn't
493 * properly handling SHELL_COMMAND_TRANSACTION.
494 */
495status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
496 uint32_t flags) {
497 status_t err;
498
499 switch (code) {
500 case SHELL_COMMAND_TRANSACTION: {
501 int in = data.readFileDescriptor();
502 int out = data.readFileDescriptor();
503 int err = data.readFileDescriptor();
504 int argc = data.readInt32();
505 Vector<String8> args;
506 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
507 args.add(String8(data.readString16()));
508 }
509 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
510 sp<IResultReceiver> resultReceiver =
511 IResultReceiver::asInterface(data.readStrongBinder());
512
513 FILE* fin = fdopen(in, "r");
514 FILE* fout = fdopen(out, "w");
515 FILE* ferr = fdopen(err, "w");
516
517 if (fin == NULL || fout == NULL || ferr == NULL) {
518 resultReceiver->send(NO_MEMORY);
519 } else {
520 err = command(fin, fout, ferr, args);
521 resultReceiver->send(err);
522 }
523
524 if (fin != NULL) {
525 fflush(fin);
526 fclose(fin);
527 }
528 if (fout != NULL) {
529 fflush(fout);
530 fclose(fout);
531 }
532 if (fout != NULL) {
533 fflush(ferr);
534 fclose(ferr);
535 }
536
537 return NO_ERROR;
Bookatzda9b8d02018-11-14 13:14:45 -0800538 } break;
Yi Jinb592e3b2018-02-01 15:17:04 -0800539 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
540 }
541}
542
543status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
544 const int argCount = args.size();
545
546 if (argCount >= 1) {
547 if (!args[0].compare(String8("privacy"))) {
548 return cmd_privacy(in, out, err, args);
549 }
Yi Jin4e843102018-02-14 15:36:18 -0800550 if (!args[0].compare(String8("throttler"))) {
551 mThrottler->dump(out);
552 return NO_ERROR;
553 }
Yi Jin908c02f2018-06-22 16:51:40 -0700554 if (!args[0].compare(String8("section"))) {
555 int id = atoi(args[1]);
556 int idx = 0;
557 while (SECTION_LIST[idx] != NULL) {
558 const Section* section = SECTION_LIST[idx];
559 if (section->id == id) {
560 fprintf(out, "Section[%d] %s\n", id, section->name.string());
561 break;
562 }
563 idx++;
564 }
565 return NO_ERROR;
566 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800567 }
568 return cmd_help(out);
569}
570
571status_t IncidentService::cmd_help(FILE* out) {
572 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
573 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700574 fprintf(out, " Prints/parses for the section id.\n\n");
575 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
576 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800577 fprintf(out, "usage: adb shell cmd incident throttler\n");
578 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800579 return NO_ERROR;
580}
581
582static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
583 if (p == NULL) return;
Joe Onorato99598ee2019-02-11 15:55:13 +0000584 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->policy);
Yi Jinb592e3b2018-02-01 15:17:04 -0800585 if (p->children == NULL) return;
586 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
587 printPrivacy(p->children[i], out, indent + " ");
588 }
589}
590
591status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000592 (void)in;
593
Yi Jinb592e3b2018-02-01 15:17:04 -0800594 const int argCount = args.size();
595 if (argCount >= 3) {
596 String8 opt = args[1];
597 int sectionId = atoi(args[2].string());
598
599 const Privacy* p = get_privacy_of_section(sectionId);
600 if (p == NULL) {
601 fprintf(err, "Can't find section id %d\n", sectionId);
602 return NO_ERROR;
603 }
604 fprintf(err, "Get privacy for %d\n", sectionId);
605 if (opt == "print") {
606 printPrivacy(p, out, String8(""));
607 } else if (opt == "parse") {
Joe Onorato99598ee2019-02-11 15:55:13 +0000608 /*
Yi Jinb592e3b2018-02-01 15:17:04 -0800609 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700610 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800611 if (error != NO_ERROR) {
612 fprintf(err, "Error reading from stdin\n");
613 return error;
614 }
615 fprintf(err, "Read %zu bytes\n", buf.size());
Joe Onorato99598ee2019-02-11 15:55:13 +0000616 PrivacyFilter pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800617
618 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
619 error = pBuf.strip(spec);
620 if (error != NO_ERROR) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000621 fprintf(err, "Error strip pii fields with spec %d\n", spec.policy);
Yi Jinb592e3b2018-02-01 15:17:04 -0800622 return error;
623 }
624 return pBuf.flush(fileno(out));
Joe Onorato99598ee2019-02-11 15:55:13 +0000625 */
626 return -1;
Yi Jinb592e3b2018-02-01 15:17:04 -0800627 }
628 } else {
629 return cmd_help(out);
630 }
631 return NO_ERROR;
632}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700633
634} // namespace incidentd
635} // namespace os
636} // namespace android