BandwidthController: validate interface / chain names
Only allow alphanumeric, dashes, underscores, or colons in
interface and chain names. First character must be alphanumeric.
Bug: 14320836
Bug: 14323009
Change-Id: Ieac729719d0f9038f60c7afcb327f17d292d6ca6
diff --git a/BandwidthController.cpp b/BandwidthController.cpp
index 65be1d1..a7c2c2c 100644
--- a/BandwidthController.cpp
+++ b/BandwidthController.cpp
@@ -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 @@
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 @@
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 @@
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 @@
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::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::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 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 @@
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);