Loading cmds/incident/main.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -263,6 +263,9 @@ main(int argc, char** argv) return 1; } } if (destination == DEST_UNSET) { destination = DEST_STDOUT; } string pkg; string cls; Loading cmds/incidentd/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ cc_binary { "-Wno-missing-field-initializers", "-Wno-unused-variable", "-Wunused-parameter", "-Wno-tautological-undefined-compare", // Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed. "-Wno-error=implicit-fallthrough", Loading Loading @@ -96,6 +97,7 @@ cc_test { "-Wno-unused-variable", "-Wunused-parameter", "-g", "-Wno-tautological-undefined-compare", // Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed. "-Wno-error=implicit-fallthrough", Loading cmds/incidentd/src/IncidentService.cpp +26 −22 Original line number Diff line number Diff line Loading @@ -174,12 +174,11 @@ void ReportHandler::schedule_send_broadcasts_locked() { } void ReportHandler::take_report() { // Cycle the batch // Cycle the batch and throttle. sp<ReportBatch> batch; { unique_lock<mutex> lock(mLock); batch = mBatch; mBatch = new ReportBatch(); batch = mThrottler->filterBatch(mBatch); } if (batch->empty()) { Loading @@ -189,13 +188,6 @@ void ReportHandler::take_report() { sp<Reporter> reporter = new Reporter(mWorkDirectory, batch); // TODO: Do we really want to clear the reports if we throttle? Should we only throttle // requests going to dropbox? How do we reconcile throttling with testing? if (mThrottler->shouldThrottle()) { ALOGW("RunReport got throttled."); return; } // Take the report, which might take a while. More requests might queue // up while we're doing this, and we'll handle them in their next batch. // TODO: We should further rate-limit the reports to no more than N per time-period. Loading @@ -203,7 +195,13 @@ void ReportHandler::take_report() { size_t reportByteSize = 0; reporter->runReport(&reportByteSize); // Tell the throttler how big it was, for the next throttling. // TODO: This still isn't ideal. The throttler really should just track the // persisted reqeusts, but changing Reporter::runReport() to track that individually // will be a big change. if (batch->hasPersistedReports()) { mThrottler->addReportSize(reportByteSize); } // Kick off the next steps, one of which is to send any new or otherwise remaining // approvals, and one of which is to send any new or remaining broadcasts. Loading Loading @@ -247,11 +245,11 @@ IncidentService::IncidentService(const sp<Looper>& handlerLooper) { IncidentService::~IncidentService() {} Status IncidentService::reportIncident(const IncidentReportArgs& args) { // TODO: Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. IncidentReportArgs argsCopy(args); // TODO: This function should reject the LOCAL privacy policy. // Those have to stream. // Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy())); // TODO: Check that the broadcast recevier has the proper permissions // TODO: Maybe we should consider relaxing the permissions if it's going to Loading @@ -261,8 +259,15 @@ Status IncidentService::reportIncident(const IncidentReportArgs& args) { return status; } // If they asked for the LOCAL privacy policy, give them EXPLICT. LOCAL has to // be streamed. (This only applies to shell/root, because everyone else would have // been rejected by checkIncidentPermissions()). if (argsCopy.getPrivacyPolicy() < PRIVACY_POLICY_EXPLICIT) { ALOGI("Demoting privacy policy to EXPLICT for persisted report."); argsCopy.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT); } // If they didn't specify a component, use dropbox. IncidentReportArgs argsCopy(args); if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) { argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName()); argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName()); Loading @@ -276,22 +281,21 @@ Status IncidentService::reportIncident(const IncidentReportArgs& args) { Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args, const sp<IIncidentReportStatusListener>& listener, const unique_fd& stream) { // TODO: Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. // TODO: Only shell should be able to do a LOCAL privacy policy report. IncidentReportArgs argsCopy(args); // Streaming reports can not also be broadcast. IncidentReportArgs argsCopy(args); argsCopy.setReceiverPkg(""); argsCopy.setReceiverCls(""); // Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy())); Status status = checkIncidentPermissions(argsCopy); if (!status.isOk()) { return status; } // The ReportRequest takes ownership of the fd, so we need to dup it. int fd = dup(stream.get()); if (fd < 0) { Loading cmds/incidentd/src/Privacy.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -18,17 +18,30 @@ #include <android/os/IncidentReportArgs.h> #include <stdlib.h> #include <strstream> namespace android { namespace os { namespace incidentd { using namespace android::os; using std::strstream; static const bool kEncryptionEnabled = false; uint64_t encode_field_id(const Privacy* p) { return (uint64_t)p->type << 32 | p->field_id; } string Privacy::toString() const { if (this == NULL) { return "Privacy{null}"; } strstream os; os << "Privacy{field_id=" << field_id << " type=" << ((int)type) << " children=" << ((void*)children) << " policy=" << ((int)policy) << "}"; return os.str(); } const Privacy* lookup(const Privacy* p, uint32_t fieldId) { if (p->children == NULL) return NULL; for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated. Loading Loading @@ -87,6 +100,16 @@ bool PrivacySpec::RequireAll() const { return mPolicy == android::os::PRIVACY_POLICY_LOCAL; } uint8_t cleanup_privacy_policy(uint8_t policy) { if (policy >= PRIVACY_POLICY_AUTOMATIC) { return PRIVACY_POLICY_AUTOMATIC; } if (policy >= PRIVACY_POLICY_EXPLICIT) { return PRIVACY_POLICY_EXPLICIT; } return PRIVACY_POLICY_LOCAL; } } // namespace incidentd } // namespace os } // namespace android cmds/incidentd/src/Privacy.h +8 −0 Original line number Diff line number Diff line Loading @@ -50,8 +50,11 @@ struct Privacy { // DESTINATION Enum in frameworks/base/core/proto/android/privacy.proto. uint8_t policy; // A list of regexp rules for stripping string fields in proto. const char** patterns; string toString() const; }; // Encode field id used by ProtoOutputStream. Loading Loading @@ -90,6 +93,11 @@ private: // TODO: Add privacy flag in incident.proto and auto generate it inside Privacy. bool sectionEncryption(int section_id); /** * If a privacy policy is other than the defined values, update it to a real one. */ uint8_t cleanup_privacy_policy(uint8_t policy); } // namespace incidentd } // namespace os } // namespace android Loading Loading
cmds/incident/main.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -263,6 +263,9 @@ main(int argc, char** argv) return 1; } } if (destination == DEST_UNSET) { destination = DEST_STDOUT; } string pkg; string cls; Loading
cmds/incidentd/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ cc_binary { "-Wno-missing-field-initializers", "-Wno-unused-variable", "-Wunused-parameter", "-Wno-tautological-undefined-compare", // Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed. "-Wno-error=implicit-fallthrough", Loading Loading @@ -96,6 +97,7 @@ cc_test { "-Wno-unused-variable", "-Wunused-parameter", "-g", "-Wno-tautological-undefined-compare", // Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed. "-Wno-error=implicit-fallthrough", Loading
cmds/incidentd/src/IncidentService.cpp +26 −22 Original line number Diff line number Diff line Loading @@ -174,12 +174,11 @@ void ReportHandler::schedule_send_broadcasts_locked() { } void ReportHandler::take_report() { // Cycle the batch // Cycle the batch and throttle. sp<ReportBatch> batch; { unique_lock<mutex> lock(mLock); batch = mBatch; mBatch = new ReportBatch(); batch = mThrottler->filterBatch(mBatch); } if (batch->empty()) { Loading @@ -189,13 +188,6 @@ void ReportHandler::take_report() { sp<Reporter> reporter = new Reporter(mWorkDirectory, batch); // TODO: Do we really want to clear the reports if we throttle? Should we only throttle // requests going to dropbox? How do we reconcile throttling with testing? if (mThrottler->shouldThrottle()) { ALOGW("RunReport got throttled."); return; } // Take the report, which might take a while. More requests might queue // up while we're doing this, and we'll handle them in their next batch. // TODO: We should further rate-limit the reports to no more than N per time-period. Loading @@ -203,7 +195,13 @@ void ReportHandler::take_report() { size_t reportByteSize = 0; reporter->runReport(&reportByteSize); // Tell the throttler how big it was, for the next throttling. // TODO: This still isn't ideal. The throttler really should just track the // persisted reqeusts, but changing Reporter::runReport() to track that individually // will be a big change. if (batch->hasPersistedReports()) { mThrottler->addReportSize(reportByteSize); } // Kick off the next steps, one of which is to send any new or otherwise remaining // approvals, and one of which is to send any new or remaining broadcasts. Loading Loading @@ -247,11 +245,11 @@ IncidentService::IncidentService(const sp<Looper>& handlerLooper) { IncidentService::~IncidentService() {} Status IncidentService::reportIncident(const IncidentReportArgs& args) { // TODO: Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. IncidentReportArgs argsCopy(args); // TODO: This function should reject the LOCAL privacy policy. // Those have to stream. // Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy())); // TODO: Check that the broadcast recevier has the proper permissions // TODO: Maybe we should consider relaxing the permissions if it's going to Loading @@ -261,8 +259,15 @@ Status IncidentService::reportIncident(const IncidentReportArgs& args) { return status; } // If they asked for the LOCAL privacy policy, give them EXPLICT. LOCAL has to // be streamed. (This only applies to shell/root, because everyone else would have // been rejected by checkIncidentPermissions()). if (argsCopy.getPrivacyPolicy() < PRIVACY_POLICY_EXPLICIT) { ALOGI("Demoting privacy policy to EXPLICT for persisted report."); argsCopy.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT); } // If they didn't specify a component, use dropbox. IncidentReportArgs argsCopy(args); if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) { argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName()); argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName()); Loading @@ -276,22 +281,21 @@ Status IncidentService::reportIncident(const IncidentReportArgs& args) { Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args, const sp<IIncidentReportStatusListener>& listener, const unique_fd& stream) { // TODO: Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. // TODO: Only shell should be able to do a LOCAL privacy policy report. IncidentReportArgs argsCopy(args); // Streaming reports can not also be broadcast. IncidentReportArgs argsCopy(args); argsCopy.setReceiverPkg(""); argsCopy.setReceiverCls(""); // Validate that the privacy policy is one of the real ones. // If it isn't, clamp it to the next more restrictive real one. argsCopy.setPrivacyPolicy(cleanup_privacy_policy(args.getPrivacyPolicy())); Status status = checkIncidentPermissions(argsCopy); if (!status.isOk()) { return status; } // The ReportRequest takes ownership of the fd, so we need to dup it. int fd = dup(stream.get()); if (fd < 0) { Loading
cmds/incidentd/src/Privacy.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -18,17 +18,30 @@ #include <android/os/IncidentReportArgs.h> #include <stdlib.h> #include <strstream> namespace android { namespace os { namespace incidentd { using namespace android::os; using std::strstream; static const bool kEncryptionEnabled = false; uint64_t encode_field_id(const Privacy* p) { return (uint64_t)p->type << 32 | p->field_id; } string Privacy::toString() const { if (this == NULL) { return "Privacy{null}"; } strstream os; os << "Privacy{field_id=" << field_id << " type=" << ((int)type) << " children=" << ((void*)children) << " policy=" << ((int)policy) << "}"; return os.str(); } const Privacy* lookup(const Privacy* p, uint32_t fieldId) { if (p->children == NULL) return NULL; for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated. Loading Loading @@ -87,6 +100,16 @@ bool PrivacySpec::RequireAll() const { return mPolicy == android::os::PRIVACY_POLICY_LOCAL; } uint8_t cleanup_privacy_policy(uint8_t policy) { if (policy >= PRIVACY_POLICY_AUTOMATIC) { return PRIVACY_POLICY_AUTOMATIC; } if (policy >= PRIVACY_POLICY_EXPLICIT) { return PRIVACY_POLICY_EXPLICIT; } return PRIVACY_POLICY_LOCAL; } } // namespace incidentd } // namespace os } // namespace android
cmds/incidentd/src/Privacy.h +8 −0 Original line number Diff line number Diff line Loading @@ -50,8 +50,11 @@ struct Privacy { // DESTINATION Enum in frameworks/base/core/proto/android/privacy.proto. uint8_t policy; // A list of regexp rules for stripping string fields in proto. const char** patterns; string toString() const; }; // Encode field id used by ProtoOutputStream. Loading Loading @@ -90,6 +93,11 @@ private: // TODO: Add privacy flag in incident.proto and auto generate it inside Privacy. bool sectionEncryption(int section_id); /** * If a privacy policy is other than the defined values, update it to a real one. */ uint8_t cleanup_privacy_policy(uint8_t policy); } // namespace incidentd } // namespace os } // namespace android Loading