OSDN Git Service

BandwidthController: validate interface / chain names
authorNick Kralevich <nnk@google.com>
Thu, 1 May 2014 20:10:45 +0000 (13:10 -0700)
committerNick Kralevich <nnk@google.com>
Thu, 1 May 2014 21:40:02 +0000 (14:40 -0700)
Only allow alphanumeric, dashes, underscores, or colons in
interface and chain names. First character must be alphanumeric.

Bug: 14320836
Bug: 14323009
Change-Id: Ieac729719d0f9038f60c7afcb327f17d292d6ca6

BandwidthController.cpp
BandwidthController.h

index 65be1d1..a7c2c2c 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #define __STDC_FORMAT_MACROS 1
 #include <inttypes.h>
@@ -707,6 +708,11 @@ int BandwidthController::setInterfaceQuota(const char *iface, int64_t maxBytes)
     std::list<QuotaInfo>::iterator it;
     std::string quotaCmd;
 
+    if (!isNameLegal(iface)) {
+        ALOGE("setInterfaceQuota: Invalid iface \"%s\"", iface);
+        return -1;
+    }
+
     if (!maxBytes) {
         /* Don't talk about -1, deprecate it. */
         ALOGE("Invalid bytes value. 1..max_int64.");
@@ -771,11 +777,37 @@ int BandwidthController::getInterfaceSharedQuota(int64_t *bytes) {
     return getInterfaceQuota("shared", bytes);
 }
 
+bool BandwidthController::isNameLegal(const char* name) {
+    size_t i;
+    size_t name_len = strlen(name);
+    if (name_len == 0) {
+        return false;
+    }
+
+    /* First character must be alphanumeric */
+    if (!isalnum(name[0])) {
+        return false;
+    }
+
+    for (i = 1; i < name_len; i++) {
+        if (!isalnum(name[i]) && (name[i] != '_') && (name[i] != '-') && (name[i] != ':')) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 int BandwidthController::getInterfaceQuota(const char *costName, int64_t *bytes) {
     FILE *fp;
     char *fname;
     int scanRes;
 
+    if (!isNameLegal(costName)) {
+        ALOGE("getInterfaceQuota: Invalid costName \"%s\"", costName);
+        return -1;
+    }
+
     asprintf(&fname, "/proc/net/xt_quota/%s", costName);
     fp = fopen(fname, "r");
     free(fname);
@@ -797,6 +829,11 @@ int BandwidthController::removeInterfaceQuota(const char *iface) {
     const char *costName;
     std::list<QuotaInfo>::iterator it;
 
+    if (!isNameLegal(iface)) {
+        ALOGE("removeInterfaceQuota: Invalid iface \"%s\"", iface);
+        return -1;
+    }
+
     if (StrncpyAndCheck(ifn, iface, sizeof(ifn))) {
         ALOGE("Interface name longer than %d", MAX_IFACENAME_LEN);
         return -1;
@@ -826,6 +863,11 @@ int BandwidthController::updateQuota(const char *quotaName, int64_t bytes) {
     FILE *fp;
     char *fname;
 
+    if (!isNameLegal(quotaName)) {
+        ALOGE("updateQuota: Invalid quotaName \"%s\"", quotaName);
+        return -1;
+    }
+
     asprintf(&fname, "/proc/net/xt_quota/%s", quotaName);
     fp = fopen(fname, "w");
     free(fname);
@@ -1000,6 +1042,11 @@ int BandwidthController::removeSharedAlert(void) {
 int BandwidthController::setInterfaceAlert(const char *iface, int64_t bytes) {
     std::list<QuotaInfo>::iterator it;
 
+    if (!isNameLegal(iface)) {
+        ALOGE("setInterfaceAlert: Invalid iface \"%s\"", iface);
+        return -1;
+    }
+
     if (!bytes) {
         ALOGE("Invalid bytes value. 1..max_int64.");
         return -1;
@@ -1020,6 +1067,11 @@ int BandwidthController::setInterfaceAlert(const char *iface, int64_t bytes) {
 int BandwidthController::removeInterfaceAlert(const char *iface) {
     std::list<QuotaInfo>::iterator it;
 
+    if (!isNameLegal(iface)) {
+        ALOGE("removeInterfaceAlert: Invalid iface \"%s\"", iface);
+        return -1;
+    }
+
     for (it = quotaIfaces.begin(); it != quotaIfaces.end(); it++) {
         if (it->ifaceName == iface)
             break;
@@ -1039,6 +1091,11 @@ int BandwidthController::setCostlyAlert(const char *costName, int64_t bytes, int
     int res = 0;
     char *alertName;
 
+    if (!isNameLegal(costName)) {
+        ALOGE("setCostlyAlert: Invalid costName \"%s\"", costName);
+        return -1;
+    }
+
     if (!bytes) {
         ALOGE("Invalid bytes value. 1..max_int64.");
         return -1;
@@ -1064,6 +1121,11 @@ int BandwidthController::removeCostlyAlert(const char *costName, int64_t *alertB
     char *alertName;
     int res = 0;
 
+    if (!isNameLegal(costName)) {
+        ALOGE("removeCostlyAlert: Invalid costName \"%s\"", costName);
+        return -1;
+    }
+
     asprintf(&alertName, "%sAlert", costName);
     if (!*alertBytes) {
         ALOGE("No prior alert set for %s alert", costName);
index 2aca2cd..6b7b5d3 100644 (file)
@@ -202,6 +202,7 @@ protected:
     std::list<int /*appUid*/> niceAppUids;
 
 private:
+    bool isNameLegal(const char* name);
     static const char *IPT_FLUSH_COMMANDS[];
     static const char *IPT_CLEANUP_COMMANDS[];
     static const char *IPT_SETUP_COMMANDS[];