blob: 53c7b744ee0fc0cfdf0f0654bc7eef31417f1c31 [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
Rafal Slawik1334f1a2022-01-12 17:13:33 +000046#define DEFAULT_BYTES_SIZE_LIMIT (400 * 1024 * 1024) // 400MB
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)
Kevin Jeon4ee5ba59e2022-07-18 20:26:38 +000050// Skip logs (1100 - 1108), traces (1200 - 1202), dumpsys (3000 - 3024, 3027 - 3056, 4000 - 4001)
51// because they are already in the bug report.
Mike Ma5a57d792019-08-21 14:52:46 -070052#define SKIPPED_DUMPSTATE_SECTIONS { \
53 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
Kevin Jeon4ee5ba59e2022-07-18 20:26:38 +000054 1200, 1201, 1202, /* Native, hal, java traces */ \
Kevin Jeonb8143662022-10-10 16:57:53 +000055 3018, /* dumpsys meminfo*/ }
Mike Ma85434ec2018-11-27 10:32:31 -080056
Yi Jin6cacbcb2018-03-30 14:04:52 -070057namespace android {
58namespace os {
59namespace incidentd {
60
Joe Onorato99598ee2019-02-11 15:55:13 +000061String16 const APPROVE_INCIDENT_REPORTS("android.permission.APPROVE_INCIDENT_REPORTS");
Joe Onorato1754d742016-11-21 17:51:35 -080062String16 const DUMP_PERMISSION("android.permission.DUMP");
63String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
64
Yi Jinb592e3b2018-02-01 15:17:04 -080065static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080066 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080067 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080068 if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
Joe Onorato99598ee2019-02-11 15:55:13 +000069 // Root and shell are ok.
70 return Status::ok();
71 }
72
73 if (checkCallingPermission(APPROVE_INCIDENT_REPORTS)) {
74 // Permission controller (this is a singleton permission that is always granted
75 // exactly for PermissionController) is allowed to access incident reports
76 // so it can show the user info about what they are approving.
Yi Jin437aa6e2018-01-10 11:34:26 -080077 return Status::ok();
78 }
79
Yi Jin4bab3a12018-01-10 16:50:59 -080080 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080081 if (!checkCallingPermission(DUMP_PERMISSION)) {
82 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080083 callingPid, callingUid);
84 return Status::fromExceptionCode(
85 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080086 "Calling process does not have permission: android.permission.DUMP");
87 }
88 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
89 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
Yi Jinb592e3b2018-02-01 15:17:04 -080090 callingPid, callingUid);
91 return Status::fromExceptionCode(
92 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080093 "Calling process does not have permission: android.permission.USAGE_STATS");
94 }
Yi Jin4bab3a12018-01-10 16:50:59 -080095
96 // checking calling request uid permission.
Joe Onorato99598ee2019-02-11 15:55:13 +000097 switch (args.getPrivacyPolicy()) {
98 case PRIVACY_POLICY_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080099 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
100 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -0800101 callingPid, callingUid);
102 return Status::fromExceptionCode(
103 Status::EX_SECURITY,
104 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800105 }
Bookatzda9b8d02018-11-14 13:14:45 -0800106 break;
Joe Onorato99598ee2019-02-11 15:55:13 +0000107 case PRIVACY_POLICY_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -0800108 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
Bookatzda9b8d02018-11-14 13:14:45 -0800109 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -0800110 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -0800111 callingPid, callingUid);
112 return Status::fromExceptionCode(
113 Status::EX_SECURITY,
114 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800115 }
Bookatzda9b8d02018-11-14 13:14:45 -0800116 break;
Yi Jin4bab3a12018-01-10 16:50:59 -0800117 }
Joe Onorato1754d742016-11-21 17:51:35 -0800118 return Status::ok();
119}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700120
Joe Onorato99598ee2019-02-11 15:55:13 +0000121static string build_uri(const string& pkg, const string& cls, const string& id) {
Yao Chencbafce92019-04-01 15:56:44 -0700122 return "content://android.os.IncidentManager/pending?pkg="
123 + pkg + "&receiver=" + cls + "&r=" + id;
Joe Onorato1754d742016-11-21 17:51:35 -0800124}
125
Joe Onorato1754d742016-11-21 17:51:35 -0800126// ================================================================================
Joe Onorato99598ee2019-02-11 15:55:13 +0000127ReportHandler::ReportHandler(const sp<WorkDirectory>& workDirectory,
Mike Ma643de922019-12-17 10:56:17 -0800128 const sp<Broadcaster>& broadcaster,
129 const sp<Looper>& handlerLooper,
130 const sp<Throttler>& throttler,
131 const vector<BringYourOwnSection*>& registeredSections)
Joe Onorato99598ee2019-02-11 15:55:13 +0000132 :mLock(),
133 mWorkDirectory(workDirectory),
134 mBroadcaster(broadcaster),
135 mHandlerLooper(handlerLooper),
136 mBacklogDelay(DEFAULT_DELAY_NS),
137 mThrottler(throttler),
Mike Ma643de922019-12-17 10:56:17 -0800138 mRegisteredSections(registeredSections),
Joe Onorato99598ee2019-02-11 15:55:13 +0000139 mBatch(new ReportBatch()) {
140}
Joe Onorato1754d742016-11-21 17:51:35 -0800141
Joe Onorato99598ee2019-02-11 15:55:13 +0000142ReportHandler::~ReportHandler() {
143}
Joe Onorato1754d742016-11-21 17:51:35 -0800144
Yi Jinb592e3b2018-02-01 15:17:04 -0800145void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800146 switch (message.what) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000147 case WHAT_TAKE_REPORT:
148 take_report();
Joe Onorato1754d742016-11-21 17:51:35 -0800149 break;
Joe Onorato99598ee2019-02-11 15:55:13 +0000150 case WHAT_SEND_BROADCASTS:
151 send_broadcasts();
Joe Onorato1754d742016-11-21 17:51:35 -0800152 break;
153 }
154}
155
Joe Onorato99598ee2019-02-11 15:55:13 +0000156void ReportHandler::schedulePersistedReport(const IncidentReportArgs& args) {
Mike Mab98050f2020-03-30 13:37:31 -0700157 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000158 mBatch->addPersistedReport(args);
159 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
160 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
Joe Onorato1754d742016-11-21 17:51:35 -0800161}
162
Joe Onorato99598ee2019-02-11 15:55:13 +0000163void ReportHandler::scheduleStreamingReport(const IncidentReportArgs& args,
164 const sp<IIncidentReportStatusListener>& listener, int streamFd) {
Mike Mab98050f2020-03-30 13:37:31 -0700165 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000166 mBatch->addStreamingReport(args, listener, streamFd);
167 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
168 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
169}
170
171void ReportHandler::scheduleSendBacklog() {
Joe Onorato1754d742016-11-21 17:51:35 -0800172 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000173 mBacklogDelay = DEFAULT_DELAY_NS;
174 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800175}
176
Joe Onorato99598ee2019-02-11 15:55:13 +0000177void ReportHandler::schedule_send_broadcasts_locked() {
178 mHandlerLooper->removeMessages(this, WHAT_SEND_BROADCASTS);
179 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BROADCASTS));
Joe Onorato1754d742016-11-21 17:51:35 -0800180}
181
Joe Onorato99598ee2019-02-11 15:55:13 +0000182void ReportHandler::take_report() {
Joe Onoratoe5472052019-04-24 16:27:33 -0700183 // Cycle the batch and throttle.
Joe Onorato99598ee2019-02-11 15:55:13 +0000184 sp<ReportBatch> batch;
185 {
186 unique_lock<mutex> lock(mLock);
Joe Onoratoe5472052019-04-24 16:27:33 -0700187 batch = mThrottler->filterBatch(mBatch);
Joe Onorato1754d742016-11-21 17:51:35 -0800188 }
189
Joe Onorato99598ee2019-02-11 15:55:13 +0000190 if (batch->empty()) {
191 // Nothing to do.
192 return;
193 }
194
Mike Ma643de922019-12-17 10:56:17 -0800195 sp<Reporter> reporter = new Reporter(mWorkDirectory, batch, mRegisteredSections);
Joe Onorato99598ee2019-02-11 15:55:13 +0000196
Joe Onorato1754d742016-11-21 17:51:35 -0800197 // Take the report, which might take a while. More requests might queue
198 // up while we're doing this, and we'll handle them in their next batch.
199 // TODO: We should further rate-limit the reports to no more than N per time-period.
Joe Onorato99598ee2019-02-11 15:55:13 +0000200 // TODO: Move this inside reporter.
Yi Jin4e843102018-02-14 15:36:18 -0800201 size_t reportByteSize = 0;
Joe Onorato99598ee2019-02-11 15:55:13 +0000202 reporter->runReport(&reportByteSize);
203
Joe Onoratoe5472052019-04-24 16:27:33 -0700204 // Tell the throttler how big it was, for the next throttling.
205 // TODO: This still isn't ideal. The throttler really should just track the
206 // persisted reqeusts, but changing Reporter::runReport() to track that individually
207 // will be a big change.
208 if (batch->hasPersistedReports()) {
209 mThrottler->addReportSize(reportByteSize);
210 }
Joe Onorato99598ee2019-02-11 15:55:13 +0000211
212 // Kick off the next steps, one of which is to send any new or otherwise remaining
213 // approvals, and one of which is to send any new or remaining broadcasts.
214 {
Joe Onorato1754d742016-11-21 17:51:35 -0800215 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000216 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800217 }
218}
219
Joe Onorato99598ee2019-02-11 15:55:13 +0000220void ReportHandler::send_broadcasts() {
221 Broadcaster::broadcast_status_t result = mBroadcaster->sendBroadcasts();
222 if (result == Broadcaster::BROADCASTS_FINISHED) {
223 // We're done.
224 unique_lock<mutex> lock(mLock);
225 mBacklogDelay = DEFAULT_DELAY_NS;
226 } else if (result == Broadcaster::BROADCASTS_REPEAT) {
227 // It worked, but there are more.
228 unique_lock<mutex> lock(mLock);
229 mBacklogDelay = DEFAULT_DELAY_NS;
230 schedule_send_broadcasts_locked();
231 } else if (result == Broadcaster::BROADCASTS_BACKOFF) {
Joe Onorato1754d742016-11-21 17:51:35 -0800232 // There was a failure. Exponential backoff.
233 unique_lock<mutex> lock(mLock);
234 mBacklogDelay *= 2;
235 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800236 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato99598ee2019-02-11 15:55:13 +0000237 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800238 }
239}
240
241// ================================================================================
Joe Onorato99598ee2019-02-11 15:55:13 +0000242IncidentService::IncidentService(const sp<Looper>& handlerLooper) {
243 mThrottler = new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS);
244 mWorkDirectory = new WorkDirectory();
245 mBroadcaster = new Broadcaster(mWorkDirectory);
246 mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper,
Mike Ma643de922019-12-17 10:56:17 -0800247 mThrottler, mRegisteredSections);
Joe Onorato99598ee2019-02-11 15:55:13 +0000248 mBroadcaster->setHandler(mHandler);
Joe Onorato1754d742016-11-21 17:51:35 -0800249}
250
Yi Jinb592e3b2018-02-01 15:17:04 -0800251IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800252
Yi Jinb592e3b2018-02-01 15:17:04 -0800253Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onoratoe5472052019-04-24 16:27:33 -0700254 IncidentReportArgs argsCopy(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800255
Joe Onoratoe5472052019-04-24 16:27:33 -0700256 // Validate that the privacy policy is one of the real ones.
257 // If it isn't, clamp it to the next more restrictive real one.
258 argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy()));
Joe Onorato99598ee2019-02-11 15:55:13 +0000259
260 // TODO: Check that the broadcast recevier has the proper permissions
261 // TODO: Maybe we should consider relaxing the permissions if it's going to
262 // dropbox, but definitely not if it's going to the broadcaster.
Yi Jin4bab3a12018-01-10 16:50:59 -0800263 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800264 if (!status.isOk()) {
265 return status;
266 }
267
Joe Onoratoe5472052019-04-24 16:27:33 -0700268 // If they asked for the LOCAL privacy policy, give them EXPLICT. LOCAL has to
269 // be streamed. (This only applies to shell/root, because everyone else would have
270 // been rejected by checkIncidentPermissions()).
271 if (argsCopy.getPrivacyPolicy() < PRIVACY_POLICY_EXPLICIT) {
272 ALOGI("Demoting privacy policy to EXPLICT for persisted report.");
273 argsCopy.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
274 }
275
Joe Onorato99598ee2019-02-11 15:55:13 +0000276 // If they didn't specify a component, use dropbox.
Joe Onorato99598ee2019-02-11 15:55:13 +0000277 if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) {
278 argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName());
279 argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName());
280 }
281
282 mHandler->schedulePersistedReport(argsCopy);
Joe Onorato1754d742016-11-21 17:51:35 -0800283
284 return Status::ok();
285}
286
Yi Jinb592e3b2018-02-01 15:17:04 -0800287Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
288 const sp<IIncidentReportStatusListener>& listener,
Jiyong Parkb8ba2342019-11-25 11:03:38 +0900289 unique_fd stream) {
Joe Onoratoe5472052019-04-24 16:27:33 -0700290 IncidentReportArgs argsCopy(args);
Joe Onorato99598ee2019-02-11 15:55:13 +0000291
292 // Streaming reports can not also be broadcast.
Joe Onorato99598ee2019-02-11 15:55:13 +0000293 argsCopy.setReceiverPkg("");
294 argsCopy.setReceiverCls("");
295
Joe Onoratoe5472052019-04-24 16:27:33 -0700296 // Validate that the privacy policy is one of the real ones.
297 // If it isn't, clamp it to the next more restrictive real one.
298 argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy()));
299
Joe Onorato99598ee2019-02-11 15:55:13 +0000300 Status status = checkIncidentPermissions(argsCopy);
Joe Onorato1754d742016-11-21 17:51:35 -0800301 if (!status.isOk()) {
302 return status;
303 }
304
Joe Onorato99598ee2019-02-11 15:55:13 +0000305 // The ReportRequest takes ownership of the fd, so we need to dup it.
Joe Onorato1754d742016-11-21 17:51:35 -0800306 int fd = dup(stream.get());
307 if (fd < 0) {
308 return Status::fromStatusT(-errno);
309 }
310
Joe Onorato99598ee2019-02-11 15:55:13 +0000311 mHandler->scheduleStreamingReport(argsCopy, listener, fd);
Joe Onorato1754d742016-11-21 17:51:35 -0800312
313 return Status::ok();
314}
315
Jiyong Parkb8ba2342019-11-25 11:03:38 +0900316Status IncidentService::reportIncidentToDumpstate(unique_fd stream,
Mike Ma5a57d792019-08-21 14:52:46 -0700317 const sp<IIncidentReportStatusListener>& listener) {
318 uid_t caller = IPCThreadState::self()->getCallingUid();
319 if (caller != AID_ROOT && caller != AID_SHELL) {
320 ALOGW("Calling uid %d does not have permission: only ROOT or SHELL allowed", caller);
321 return Status::fromExceptionCode(Status::EX_SECURITY, "Only ROOT or SHELL allowed");
322 }
323
324 ALOGD("Stream incident report to dumpstate");
325 IncidentReportArgs incidentArgs;
326 // Privacy policy for dumpstate incident reports is always EXPLICIT.
327 incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
328
329 int skipped[] = SKIPPED_DUMPSTATE_SECTIONS;
330 for (const Section** section = SECTION_LIST; *section; section++) {
331 const int id = (*section)->id;
332 if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)
333 && !section_requires_specific_mention(id)) {
334 incidentArgs.addSection(id);
335 }
336 }
Mike Ma643de922019-12-17 10:56:17 -0800337 for (const Section* section : mRegisteredSections) {
338 if (!section_requires_specific_mention(section->id)) {
339 incidentArgs.addSection(section->id);
340 }
341 }
Mike Ma5a57d792019-08-21 14:52:46 -0700342
343 // The ReportRequest takes ownership of the fd, so we need to dup it.
344 int fd = dup(stream.get());
345 if (fd < 0) {
346 return Status::fromStatusT(-errno);
347 }
348
349 mHandler->scheduleStreamingReport(incidentArgs, listener, fd);
350
351 return Status::ok();
352}
353
Mike Ma643de922019-12-17 10:56:17 -0800354Status IncidentService::registerSection(const int id, const String16& name16,
355 const sp<IIncidentDumpCallback>& callback) {
Wenjie Zhou751c7c92020-05-14 12:49:19 -0700356 const String8 name = String8(name16);
Mike Mac2ab45a2020-01-17 06:11:24 +0000357 const uid_t callingUid = IPCThreadState::self()->getCallingUid();
Wenjie Zhou751c7c92020-05-14 12:49:19 -0700358 ALOGI("Uid %d registers section %d '%s'", callingUid, id, name.c_str());
Mike Ma643de922019-12-17 10:56:17 -0800359 if (callback == nullptr) {
360 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
361 }
Mike Ma643de922019-12-17 10:56:17 -0800362 for (int i = 0; i < mRegisteredSections.size(); i++) {
363 if (mRegisteredSections.at(i)->id == id) {
364 if (mRegisteredSections.at(i)->uid != callingUid) {
365 ALOGW("Error registering section %d: calling uid does not match", id);
366 return Status::fromExceptionCode(Status::EX_SECURITY);
367 }
Wenjie Zhou751c7c92020-05-14 12:49:19 -0700368 mRegisteredSections.at(i) = new BringYourOwnSection(id, name.c_str(), callingUid, callback);
Mike Ma643de922019-12-17 10:56:17 -0800369 return Status::ok();
370 }
371 }
Wenjie Zhou751c7c92020-05-14 12:49:19 -0700372 mRegisteredSections.push_back(new BringYourOwnSection(id, name.c_str(), callingUid, callback));
Mike Ma643de922019-12-17 10:56:17 -0800373 return Status::ok();
374}
375
376Status IncidentService::unregisterSection(const int id) {
Mike Ma643de922019-12-17 10:56:17 -0800377 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Mike Mac2ab45a2020-01-17 06:11:24 +0000378 ALOGI("Uid %d unregisters section %d", callingUid, id);
379
Mike Ma643de922019-12-17 10:56:17 -0800380 for (auto it = mRegisteredSections.begin(); it != mRegisteredSections.end(); it++) {
381 if ((*it)->id == id) {
382 if ((*it)->uid != callingUid) {
383 ALOGW("Error unregistering section %d: calling uid does not match", id);
384 return Status::fromExceptionCode(Status::EX_SECURITY);
385 }
386 mRegisteredSections.erase(it);
387 return Status::ok();
388 }
389 }
390 ALOGW("Section %d not found", id);
391 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
392}
393
Yi Jinb592e3b2018-02-01 15:17:04 -0800394Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800395 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
396 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800397 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800398 }
Yi Jinadd11e92017-07-30 16:10:07 -0700399
Joe Onorato1754d742016-11-21 17:51:35 -0800400 // When system_server is up and running, schedule the dropbox task to run.
Joe Onorato99598ee2019-02-11 15:55:13 +0000401 mBroadcaster->reset();
402 mHandler->scheduleSendBacklog();
403
404 return Status::ok();
405}
406
407Status IncidentService::getIncidentReportList(const String16& pkg16, const String16& cls16,
408 vector<String16>* result) {
409 status_t err;
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000410 const string pkg(String8(pkg16).c_str());
411 const string cls(String8(cls16).c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000412
413 // List the reports
414 vector<sp<ReportFile>> all;
415 err = mWorkDirectory->getReports(&all, 0);
416 if (err != NO_ERROR) {
417 return Status::fromStatusT(err);
418 }
419
420 // Find the ones that match pkg and cls.
421 for (sp<ReportFile>& file: all) {
422 err = file->loadEnvelope();
423 if (err != NO_ERROR) {
424 continue;
425 }
426 const ReportFileProto& envelope = file->getEnvelope();
427 size_t reportCount = envelope.report_size();
428 for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
429 const ReportFileProto_Report& report = envelope.report(reportIndex);
430 if (pkg == report.pkg() && cls == report.cls()) {
431 result->push_back(String16(build_uri(pkg, cls, file->getId()).c_str()));
432 break;
433 }
434 }
435 }
436
437 return Status::ok();
438}
439
440Status IncidentService::getIncidentReport(const String16& pkg16, const String16& cls16,
441 const String16& id16, IncidentManager::IncidentReport* result) {
442 status_t err;
443
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000444 const string pkg(String8(pkg16).c_str());
445 const string cls(String8(cls16).c_str());
446 const string id(String8(id16).c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000447
448 IncidentReportArgs args;
449 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, &args);
450 if (file != nullptr) {
Yao Chencbafce92019-04-01 15:56:44 -0700451 // Create pipe
452 int fds[2];
453 if (pipe(fds) != 0) {
454 ALOGW("Error opening pipe to filter incident report: %s",
455 file->getDataFileName().c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000456 return Status::ok();
457 }
Joe Onorato99598ee2019-02-11 15:55:13 +0000458 result->setTimestampNs(file->getTimestampNs());
459 result->setPrivacyPolicy(file->getEnvelope().privacy_policy());
Yao Chencbafce92019-04-01 15:56:44 -0700460 result->takeFileDescriptor(fds[0]);
461 int writeFd = fds[1];
462 // spawn a thread to write the data. Release the writeFd ownership to the thread.
463 thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); });
464
465 th.detach();
Joe Onorato99598ee2019-02-11 15:55:13 +0000466 }
467
468 return Status::ok();
469}
470
471Status IncidentService::deleteIncidentReports(const String16& pkg16, const String16& cls16,
472 const String16& id16) {
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000473 const string pkg(String8(pkg16).c_str());
474 const string cls(String8(cls16).c_str());
475 const string id(String8(id16).c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000476
477 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, nullptr);
478 if (file != nullptr) {
479 mWorkDirectory->commit(file, pkg, cls);
480 }
481 mBroadcaster->clearBroadcasts(pkg, cls, id);
482
483 return Status::ok();
484}
485
486Status IncidentService::deleteAllIncidentReports(const String16& pkg16) {
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000487 const string pkg(String8(pkg16).c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000488
489 mWorkDirectory->commitAll(pkg);
490 mBroadcaster->clearPackageBroadcasts(pkg);
Joe Onorato1754d742016-11-21 17:51:35 -0800491
492 return Status::ok();
493}
494
Yi Jinb592e3b2018-02-01 15:17:04 -0800495/**
496 * Implement our own because the default binder implementation isn't
497 * properly handling SHELL_COMMAND_TRANSACTION.
498 */
499status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
500 uint32_t flags) {
501 status_t err;
502
503 switch (code) {
504 case SHELL_COMMAND_TRANSACTION: {
505 int in = data.readFileDescriptor();
506 int out = data.readFileDescriptor();
507 int err = data.readFileDescriptor();
508 int argc = data.readInt32();
509 Vector<String8> args;
510 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
511 args.add(String8(data.readString16()));
512 }
513 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
514 sp<IResultReceiver> resultReceiver =
515 IResultReceiver::asInterface(data.readStrongBinder());
Pawan Wagh54826462023-05-16 19:52:05 +0000516 if (resultReceiver == nullptr) {
517 return BAD_VALUE;
518 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800519
520 FILE* fin = fdopen(in, "r");
521 FILE* fout = fdopen(out, "w");
522 FILE* ferr = fdopen(err, "w");
523
524 if (fin == NULL || fout == NULL || ferr == NULL) {
525 resultReceiver->send(NO_MEMORY);
526 } else {
527 err = command(fin, fout, ferr, args);
528 resultReceiver->send(err);
529 }
530
531 if (fin != NULL) {
532 fflush(fin);
533 fclose(fin);
534 }
535 if (fout != NULL) {
536 fflush(fout);
537 fclose(fout);
538 }
Pawan Wagh428871d2023-05-19 21:18:01 +0000539 if (ferr != NULL) {
Yi Jinb592e3b2018-02-01 15:17:04 -0800540 fflush(ferr);
541 fclose(ferr);
542 }
543
544 return NO_ERROR;
Bookatzda9b8d02018-11-14 13:14:45 -0800545 } break;
Yi Jinb592e3b2018-02-01 15:17:04 -0800546 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
547 }
548}
549
550status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
551 const int argCount = args.size();
552
553 if (argCount >= 1) {
554 if (!args[0].compare(String8("privacy"))) {
555 return cmd_privacy(in, out, err, args);
556 }
Yi Jin4e843102018-02-14 15:36:18 -0800557 if (!args[0].compare(String8("throttler"))) {
558 mThrottler->dump(out);
559 return NO_ERROR;
560 }
Yi Jin908c02f2018-06-22 16:51:40 -0700561 if (!args[0].compare(String8("section"))) {
Howard Ro8ff53152020-08-18 17:13:40 -0700562 if (argCount == 1) {
563 fprintf(out, "Not enough arguments for section\n");
564 return NO_ERROR;
565 }
Yi Jin908c02f2018-06-22 16:51:40 -0700566 int id = atoi(args[1]);
567 int idx = 0;
568 while (SECTION_LIST[idx] != NULL) {
569 const Section* section = SECTION_LIST[idx];
570 if (section->id == id) {
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000571 fprintf(out, "Section[%d] %s\n", id, section->name.c_str());
Yi Jin908c02f2018-06-22 16:51:40 -0700572 break;
573 }
574 idx++;
575 }
576 return NO_ERROR;
577 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800578 }
579 return cmd_help(out);
580}
581
582status_t IncidentService::cmd_help(FILE* out) {
583 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
584 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700585 fprintf(out, " Prints/parses for the section id.\n\n");
586 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
587 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800588 fprintf(out, "usage: adb shell cmd incident throttler\n");
589 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800590 return NO_ERROR;
591}
592
593static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
594 if (p == NULL) return;
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000595 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.c_str(), p->field_id, p->type, p->policy);
Yi Jinb592e3b2018-02-01 15:17:04 -0800596 if (p->children == NULL) return;
597 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
598 printPrivacy(p->children[i], out, indent + " ");
599 }
600}
601
602status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000603 (void)in;
604
Yi Jinb592e3b2018-02-01 15:17:04 -0800605 const int argCount = args.size();
606 if (argCount >= 3) {
607 String8 opt = args[1];
Tomasz Wasilczyk3815d342023-08-10 23:54:44 +0000608 int sectionId = atoi(args[2].c_str());
Yi Jinb592e3b2018-02-01 15:17:04 -0800609
610 const Privacy* p = get_privacy_of_section(sectionId);
611 if (p == NULL) {
612 fprintf(err, "Can't find section id %d\n", sectionId);
613 return NO_ERROR;
614 }
615 fprintf(err, "Get privacy for %d\n", sectionId);
616 if (opt == "print") {
617 printPrivacy(p, out, String8(""));
618 } else if (opt == "parse") {
Joe Onorato99598ee2019-02-11 15:55:13 +0000619 /*
Yi Jinb592e3b2018-02-01 15:17:04 -0800620 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700621 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800622 if (error != NO_ERROR) {
623 fprintf(err, "Error reading from stdin\n");
624 return error;
625 }
626 fprintf(err, "Read %zu bytes\n", buf.size());
Joe Onorato99598ee2019-02-11 15:55:13 +0000627 PrivacyFilter pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800628
629 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
630 error = pBuf.strip(spec);
631 if (error != NO_ERROR) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000632 fprintf(err, "Error strip pii fields with spec %d\n", spec.policy);
Yi Jinb592e3b2018-02-01 15:17:04 -0800633 return error;
634 }
635 return pBuf.flush(fileno(out));
Joe Onorato99598ee2019-02-11 15:55:13 +0000636 */
637 return -1;
Yi Jinb592e3b2018-02-01 15:17:04 -0800638 }
639 } else {
640 return cmd_help(out);
641 }
642 return NO_ERROR;
643}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700644
645} // namespace incidentd
646} // namespace os
647} // namespace android