• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 #define DEBUG false
17 #include "Log.h"
18 
19 #include "IncidentService.h"
20 
21 #include "FdBuffer.h"
22 #include "PrivacyBuffer.h"
23 #include "Reporter.h"
24 #include "incidentd_util.h"
25 #include "section_list.h"
26 
27 #include <binder/IPCThreadState.h>
28 #include <binder/IResultReceiver.h>
29 #include <binder/IServiceManager.h>
30 #include <binder/IShellCallback.h>
31 #include <cutils/log.h>
32 #include <private/android_filesystem_config.h>
33 #include <utils/Looper.h>
34 
35 #include <unistd.h>
36 
37 enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
38 
39 #define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
40 
41 #define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024)        // 20MB
42 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
43 
44 namespace android {
45 namespace os {
46 namespace incidentd {
47 
48 String16 const DUMP_PERMISSION("android.permission.DUMP");
49 String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
50 
checkIncidentPermissions(const IncidentReportArgs & args)51 static Status checkIncidentPermissions(const IncidentReportArgs& args) {
52     uid_t callingUid = IPCThreadState::self()->getCallingUid();
53     pid_t callingPid = IPCThreadState::self()->getCallingPid();
54     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 
59     // checking calling permission.
60     if (!checkCallingPermission(DUMP_PERMISSION)) {
61         ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
62               callingPid, callingUid);
63         return Status::fromExceptionCode(
64                 Status::EX_SECURITY,
65                 "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",
69               callingPid, callingUid);
70         return Status::fromExceptionCode(
71                 Status::EX_SECURITY,
72                 "Calling process does not have permission: android.permission.USAGE_STATS");
73     }
74 
75     // checking calling request uid permission.
76     switch (args.dest()) {
77         case DEST_LOCAL:
78             if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
79                 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
80                       callingPid, callingUid);
81                 return Status::fromExceptionCode(
82                         Status::EX_SECURITY,
83                         "Calling process does not have permission to get local data.");
84             }
85         case DEST_EXPLICIT:
86             if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
87                 callingUid != AID_SYSTEM) {
88                 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
89                       callingPid, callingUid);
90                 return Status::fromExceptionCode(
91                         Status::EX_SECURITY,
92                         "Calling process does not have permission to get explicit data.");
93             }
94     }
95     return Status::ok();
96 }
97 
98 // ================================================================================
ReportRequestQueue()99 ReportRequestQueue::ReportRequestQueue() {}
100 
~ReportRequestQueue()101 ReportRequestQueue::~ReportRequestQueue() {}
102 
addRequest(const sp<ReportRequest> & request)103 void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
104     unique_lock<mutex> lock(mLock);
105     mQueue.push_back(request);
106 }
107 
getNextRequest()108 sp<ReportRequest> ReportRequestQueue::getNextRequest() {
109     unique_lock<mutex> lock(mLock);
110     if (mQueue.empty()) {
111         return NULL;
112     } else {
113         sp<ReportRequest> front(mQueue.front());
114         mQueue.pop_front();
115         return front;
116     }
117 }
118 
119 // ================================================================================
ReportHandler(const sp<Looper> & handlerLooper,const sp<ReportRequestQueue> & queue,const sp<Throttler> & throttler)120 ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
121                              const sp<Throttler>& throttler)
122     : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
123       mHandlerLooper(handlerLooper),
124       mQueue(queue),
125       mThrottler(throttler) {}
126 
~ReportHandler()127 ReportHandler::~ReportHandler() {}
128 
handleMessage(const Message & message)129 void ReportHandler::handleMessage(const Message& message) {
130     switch (message.what) {
131         case WHAT_RUN_REPORT:
132             run_report();
133             break;
134         case WHAT_SEND_BACKLOG_TO_DROPBOX:
135             send_backlog_to_dropbox();
136             break;
137     }
138 }
139 
scheduleRunReport(const sp<ReportRequest> & request)140 void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
141     mQueue->addRequest(request);
142     mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
143     mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
144 }
145 
scheduleSendBacklogToDropbox()146 void ReportHandler::scheduleSendBacklogToDropbox() {
147     unique_lock<mutex> lock(mLock);
148     mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
149     schedule_send_backlog_to_dropbox_locked();
150 }
151 
schedule_send_backlog_to_dropbox_locked()152 void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
153     mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
154     mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
155 }
156 
run_report()157 void ReportHandler::run_report() {
158     sp<Reporter> reporter = new Reporter();
159 
160     // Merge all of the requests into one that has all of the
161     // requested fields.
162     while (true) {
163         sp<ReportRequest> request = mQueue->getNextRequest();
164         if (request == NULL) {
165             break;
166         }
167         reporter->batch.add(request);
168     }
169 
170     if (mThrottler->shouldThrottle()) {
171         ALOGW("RunReport got throttled.");
172         return;
173     }
174 
175     // Take the report, which might take a while. More requests might queue
176     // up while we're doing this, and we'll handle them in their next batch.
177     // TODO: We should further rate-limit the reports to no more than N per time-period.
178     size_t reportByteSize = 0;
179     Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
180     mThrottler->addReportSize(reportByteSize);
181     if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
182         unique_lock<mutex> lock(mLock);
183         schedule_send_backlog_to_dropbox_locked();
184     }
185 }
186 
send_backlog_to_dropbox()187 void ReportHandler::send_backlog_to_dropbox() {
188     if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
189         // There was a failure. Exponential backoff.
190         unique_lock<mutex> lock(mLock);
191         mBacklogDelay *= 2;
192         ALOGI("Error sending to dropbox. Trying again in %lld minutes",
193               (mBacklogDelay / (1000000000LL * 60)));
194         schedule_send_backlog_to_dropbox_locked();
195     } else {
196         mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
197     }
198 }
199 
200 // ================================================================================
IncidentService(const sp<Looper> & handlerLooper)201 IncidentService::IncidentService(const sp<Looper>& handlerLooper)
202     : mQueue(new ReportRequestQueue()),
203       mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
204     mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
205 }
206 
~IncidentService()207 IncidentService::~IncidentService() {}
208 
reportIncident(const IncidentReportArgs & args)209 Status IncidentService::reportIncident(const IncidentReportArgs& args) {
210     ALOGI("reportIncident");
211 
212     Status status = checkIncidentPermissions(args);
213     if (!status.isOk()) {
214         return status;
215     }
216 
217     mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
218 
219     return Status::ok();
220 }
221 
reportIncidentToStream(const IncidentReportArgs & args,const sp<IIncidentReportStatusListener> & listener,const unique_fd & stream)222 Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
223                                                const sp<IIncidentReportStatusListener>& listener,
224                                                const unique_fd& stream) {
225     ALOGI("reportIncidentToStream");
226 
227     Status status = checkIncidentPermissions(args);
228     if (!status.isOk()) {
229         return status;
230     }
231 
232     int fd = dup(stream.get());
233     if (fd < 0) {
234         return Status::fromStatusT(-errno);
235     }
236 
237     mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
238 
239     return Status::ok();
240 }
241 
systemRunning()242 Status IncidentService::systemRunning() {
243     if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
244         return Status::fromExceptionCode(Status::EX_SECURITY,
245                                          "Only system uid can call systemRunning");
246     }
247 
248     // When system_server is up and running, schedule the dropbox task to run.
249     mHandler->scheduleSendBacklogToDropbox();
250 
251     return Status::ok();
252 }
253 
254 /**
255  * Implement our own because the default binder implementation isn't
256  * properly handling SHELL_COMMAND_TRANSACTION.
257  */
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)258 status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
259                                      uint32_t flags) {
260     status_t err;
261 
262     switch (code) {
263         case SHELL_COMMAND_TRANSACTION: {
264             int in = data.readFileDescriptor();
265             int out = data.readFileDescriptor();
266             int err = data.readFileDescriptor();
267             int argc = data.readInt32();
268             Vector<String8> args;
269             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
270                 args.add(String8(data.readString16()));
271             }
272             sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
273             sp<IResultReceiver> resultReceiver =
274                     IResultReceiver::asInterface(data.readStrongBinder());
275 
276             FILE* fin = fdopen(in, "r");
277             FILE* fout = fdopen(out, "w");
278             FILE* ferr = fdopen(err, "w");
279 
280             if (fin == NULL || fout == NULL || ferr == NULL) {
281                 resultReceiver->send(NO_MEMORY);
282             } else {
283                 err = command(fin, fout, ferr, args);
284                 resultReceiver->send(err);
285             }
286 
287             if (fin != NULL) {
288                 fflush(fin);
289                 fclose(fin);
290             }
291             if (fout != NULL) {
292                 fflush(fout);
293                 fclose(fout);
294             }
295             if (fout != NULL) {
296                 fflush(ferr);
297                 fclose(ferr);
298             }
299 
300             return NO_ERROR;
301         }
302         default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
303     }
304 }
305 
command(FILE * in,FILE * out,FILE * err,Vector<String8> & args)306 status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
307     const int argCount = args.size();
308 
309     if (argCount >= 1) {
310         if (!args[0].compare(String8("privacy"))) {
311             return cmd_privacy(in, out, err, args);
312         }
313         if (!args[0].compare(String8("throttler"))) {
314             mThrottler->dump(out);
315             return NO_ERROR;
316         }
317     }
318     return cmd_help(out);
319 }
320 
cmd_help(FILE * out)321 status_t IncidentService::cmd_help(FILE* out) {
322     fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
323     fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
324     fprintf(out, "    Prints/parses for the section id.\n");
325     fprintf(out, "\n");
326     fprintf(out, "usage: adb shell cmd incident throttler\n");
327     fprintf(out, "    Prints the current throttler state\n");
328     return NO_ERROR;
329 }
330 
printPrivacy(const Privacy * p,FILE * out,String8 indent)331 static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
332     if (p == NULL) return;
333     fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
334     if (p->children == NULL) return;
335     for (int i = 0; p->children[i] != NULL; i++) {  // NULL-terminated.
336         printPrivacy(p->children[i], out, indent + "  ");
337     }
338 }
339 
cmd_privacy(FILE * in,FILE * out,FILE * err,Vector<String8> & args)340 status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
341     const int argCount = args.size();
342     if (argCount >= 3) {
343         String8 opt = args[1];
344         int sectionId = atoi(args[2].string());
345 
346         const Privacy* p = get_privacy_of_section(sectionId);
347         if (p == NULL) {
348             fprintf(err, "Can't find section id %d\n", sectionId);
349             return NO_ERROR;
350         }
351         fprintf(err, "Get privacy for %d\n", sectionId);
352         if (opt == "print") {
353             printPrivacy(p, out, String8(""));
354         } else if (opt == "parse") {
355             FdBuffer buf;
356             status_t error = buf.read(fileno(in), 60000);
357             if (error != NO_ERROR) {
358                 fprintf(err, "Error reading from stdin\n");
359                 return error;
360             }
361             fprintf(err, "Read %zu bytes\n", buf.size());
362             PrivacyBuffer pBuf(p, buf.data());
363 
364             PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
365             error = pBuf.strip(spec);
366             if (error != NO_ERROR) {
367                 fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
368                 return error;
369             }
370             return pBuf.flush(fileno(out));
371         }
372     } else {
373         return cmd_help(out);
374     }
375     return NO_ERROR;
376 }
377 
378 }  // namespace incidentd
379 }  // namespace os
380 }  // namespace android
381