server: check interface names in RPC arguments for validity

This patch introduces a method isIfaceName that checks interface
names from various RPCs for validity before e.g. using them as
part of iptables arguments or in filenames.

All of these RPC calls can only be called from applications
with at least the CONNECTIVITY_INTERNAL permission in recent
Android versions, so the impact of the missing checks luckily
isn't very high.

Orig-Author: Jann Horn <jann@thejh.net>

Change-Id: I80df8d745a3de99ad02d6649f0d10562c81f6b98
Signed-off-by: JP Abgrall <jpa@google.com>
diff --git a/server/InterfaceController.cpp b/server/InterfaceController.cpp
index e55114f..73e96ee 100644
--- a/server/InterfaceController.cpp
+++ b/server/InterfaceController.cpp
@@ -111,6 +111,7 @@
  */
 int InterfaceController::interfaceCommand(int argc, char *argv[], char **rbuf) {
 	int ret = -ENOSYS;
+	if (!isIfaceName(argv[2])) return -ENOENT;
 	if (sendCommand_)
 		ret = sendCommand_(argc, argv, rbuf);
 
@@ -119,6 +120,10 @@
 
 int InterfaceController::writeIPv6ProcPath(const char *interface, const char *setting, const char *value) {
 	char *path;
+	if (!isIfaceName(interface)) {
+		errno = ENOENT;
+		return -1;
+	}
 	asprintf(&path, "%s/%s/%s", ipv6_proc_path, interface, setting);
 	int success = writeFile(path, value, strlen(value));
 	free(path);
@@ -187,18 +192,25 @@
 	char buf[16];
 	int size = sizeof(buf);
 	char *path;
+	if (!isIfaceName(interface)) {
+		errno = ENOENT;
+		return -1;
+	}
 	asprintf(&path, "%s/%s/mtu", sys_net_path, interface);
 	int success = readFile(path, buf, &size);
 	if (!success && mtu)
 		*mtu = atoi(buf);
 	free(path);
 	return success;
-
 }
 
 int InterfaceController::setMtu(const char *interface, const char *mtu)
 {
 	char *path;
+	if (!isIfaceName(interface)) {
+		errno = ENOENT;
+		return -1;
+	}
 	asprintf(&path, "%s/%s/mtu", sys_net_path, interface);
 	int success = writeFile(path, mtu, strlen(mtu));
 	free(path);