Home | History | Annotate | Download | only in src
      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 
     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 // ================================================================================
     99 ReportRequestQueue::ReportRequestQueue() {}
    100 
    101 ReportRequestQueue::~ReportRequestQueue() {}
    102 
    103 void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
    104     unique_lock<mutex> lock(mLock);
    105     mQueue.push_back(request);
    106 }
    107 
    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 // ================================================================================
    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 
    127 ReportHandler::~ReportHandler() {}
    128 
    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 
    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 
    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 
    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 
    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 
    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 // ================================================================================
    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 
    207 IncidentService::~IncidentService() {}
    208 
    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 
    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 
    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  */
    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 
    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 
    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 
    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 
    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