diff options
Diffstat (limited to 'cmds/statsd/src/StatsService.cpp')
-rw-r--r-- | cmds/statsd/src/StatsService.cpp | 102 |
1 files changed, 44 insertions, 58 deletions
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index 04173b217dcb..50b64b986866 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -296,6 +296,7 @@ void StatsService::dumpIncidentSection(int out) { ADB_DUMP, &proto); proto.end(reportsListToken); proto.flush(out); + proto.clear(); } } @@ -466,23 +467,12 @@ status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) { name.assign(args[1].c_str(), args[1].size()); good = true; } else if (argCount == 3) { - // If it's a userdebug or eng build, then the shell user can - // impersonate other uids. - if (mEngBuild) { - const char* s = args[1].c_str(); - if (*s != '\0') { - char* end = NULL; - uid = strtol(s, &end, 0); - if (*end == '\0') { - name.assign(args[2].c_str(), args[2].size()); - good = true; - } - } - } else { - dprintf(out, - "The metrics can only be dumped for other UIDs on eng or userdebug " - "builds.\n"); + good = getUidFromArgs(args, 1, uid); + if (!good) { + dprintf(out, "Invalid UID. Note that the metrics can only be dumped for " + "other UIDs on eng or userdebug builds.\n"); } + name.assign(args[2].c_str(), args[2].size()); } if (!good) { print_cmd_help(out); @@ -518,23 +508,12 @@ status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& arg name.assign(args[2].c_str(), args[2].size()); good = true; } else if (argCount == 4) { - // If it's a userdebug or eng build, then the shell user can - // impersonate other uids. - if (mEngBuild) { - const char* s = args[2].c_str(); - if (*s != '\0') { - char* end = NULL; - uid = strtol(s, &end, 0); - if (*end == '\0') { - name.assign(args[3].c_str(), args[3].size()); - good = true; - } - } - } else { - dprintf(err, - "The config can only be set for other UIDs on eng or userdebug " - "builds.\n"); + good = getUidFromArgs(args, 2, uid); + if (!good) { + dprintf(err, "Invalid UID. Note that the config can only be set for " + "other UIDs on eng or userdebug builds.\n"); } + name.assign(args[3].c_str(), args[3].size()); } else if (argCount == 2 && args[1] == "remove") { good = true; } @@ -612,23 +591,12 @@ status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) { name.assign(args[1].c_str(), args[1].size()); good = true; } else if (argCount == 3) { - // If it's a userdebug or eng build, then the shell user can - // impersonate other uids. - if (mEngBuild) { - const char* s = args[1].c_str(); - if (*s != '\0') { - char* end = NULL; - uid = strtol(s, &end, 0); - if (*end == '\0') { - name.assign(args[2].c_str(), args[2].size()); - good = true; - } - } - } else { - dprintf(out, - "The metrics can only be dumped for other UIDs on eng or userdebug " - "builds.\n"); + good = getUidFromArgs(args, 1, uid); + if (!good) { + dprintf(out, "Invalid UID. Note that the metrics can only be dumped for " + "other UIDs on eng or userdebug builds.\n"); } + name.assign(args[2].c_str(), args[2].size()); } if (good) { vector<uint8_t> data; @@ -714,18 +682,14 @@ status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& ar state = atoi(args[2].c_str()); good = true; } else if (argCount == 4) { - uid = atoi(args[1].c_str()); - // If it's a userdebug or eng build, then the shell user can impersonate other uids. - // Otherwise, the uid must match the actual caller's uid. - if (mEngBuild || (uid >= 0 && (uid_t)uid == IPCThreadState::self()->getCallingUid())) { - label = atoi(args[2].c_str()); - state = atoi(args[3].c_str()); - good = true; - } else { + good = getUidFromArgs(args, 1, uid); + if (!good) { dprintf(out, - "Selecting a UID for writing AppBreadcrumb can only be done for other UIDs " - "on eng or userdebug builds.\n"); + "Invalid UID. Note that selecting a UID for writing AppBreadcrumb can only be " + "done for other UIDs on eng or userdebug builds.\n"); } + label = atoi(args[2].c_str()); + state = atoi(args[3].c_str()); } if (good) { dprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state); @@ -792,6 +756,28 @@ status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) { } } +bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) { + const char* s = args[uidArgIndex].c_str(); + if (*s == '\0') { + return false; + } + char* endc = NULL; + int64_t longUid = strtol(s, &endc, 0); + if (*endc != '\0') { + return false; + } + int32_t goodUid = static_cast<int32_t>(longUid); + if (longUid < 0 || static_cast<uint64_t>(longUid) != static_cast<uid_t>(goodUid)) { + return false; // It was not of uid_t type. + } + uid = goodUid; + + int32_t callingUid = IPCThreadState::self()->getCallingUid(); + return mEngBuild // UserDebug/EngBuild are allowed to impersonate uids. + || (callingUid == goodUid) // Anyone can 'impersonate' themselves. + || (callingUid == AID_ROOT && goodUid == AID_SHELL); // ROOT can impersonate SHELL. +} + Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version, const vector<String16>& version_string, const vector<String16>& app, |