summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2011-12-14 15:20:59 -0800
committerThe Android Automerger <android-build@android.com>2011-12-14 15:44:43 -0800
commit8a12dd0851cc2aaa1f6ffb27e5d7616733200c36 (patch)
tree3f77f052986e5e1c54dc2dddc280c05af7b8ada7
parent063af322b48ab1bb0c3e09eb0b64915ba568275b (diff)
downloadnetd-8a12dd0851cc2aaa1f6ffb27e5d7616733200c36.tar.gz
netd: fix argument interpretation bugandroid-4.0.3_r1.1android-4.0.3_r1
While working around the logwrap() issue, it was replaced with system() which could lead to various commands getting misinterpreted. We now use a system() equivalent that doesn't use "sh -c". Bug:5758556 Change-Id: I2599b526ac34bcfca18d05261286d902d547efda
-rw-r--r--BandwidthController.cpp3
-rw-r--r--NatController.cpp4
-rw-r--r--SecondaryTableController.cpp4
-rw-r--r--ThrottleController.cpp4
-rw-r--r--logwrapper.c63
5 files changed, 72 insertions, 6 deletions
diff --git a/BandwidthController.cpp b/BandwidthController.cpp
index f0a856e1..be3cb28c 100644
--- a/BandwidthController.cpp
+++ b/BandwidthController.cpp
@@ -42,6 +42,7 @@
#include <cutils/properties.h>
extern "C" int logwrap(int argc, const char **argv, int background);
+extern "C" int system_nosh(const char *command);
#include "BandwidthController.h"
@@ -185,7 +186,7 @@ int BandwidthController::runIptablesCmd(const char *cmd, IptRejectOp rejectHandl
fullCmd.insert(0, iptVer == IptIpV4 ? IPTABLES_PATH : IP6TABLES_PATH);
if (!useLogwrapCall) {
- res = system(fullCmd.c_str());
+ res = system_nosh(fullCmd.c_str());
} else {
if (StrncpyAndCheck(buffer, fullCmd.c_str(), sizeof(buffer))) {
LOGE("iptables command too long");
diff --git a/NatController.cpp b/NatController.cpp
index 5f6a46a3..ed1b095d 100644
--- a/NatController.cpp
+++ b/NatController.cpp
@@ -30,7 +30,7 @@
#include "NatController.h"
#include "SecondaryTableController.h"
-extern "C" int logwrap(int argc, const char **argv, int background);
+extern "C" int system_nosh(const char *command);
static char IPTABLES_PATH[] = "/system/bin/iptables";
static char IP_PATH[] = "/system/bin/ip";
@@ -55,7 +55,7 @@ int NatController::runCmd(const char *path, const char *cmd) {
}
asprintf(&buffer, "%s %s", path, cmd);
- res = system(buffer);
+ res = system_nosh(buffer);
free(buffer);
return res;
}
diff --git a/SecondaryTableController.cpp b/SecondaryTableController.cpp
index 1be1c795..287bba5d 100644
--- a/SecondaryTableController.cpp
+++ b/SecondaryTableController.cpp
@@ -31,6 +31,8 @@
#include <cutils/log.h>
#include <cutils/properties.h>
+extern "C" int system_nosh(const char *command);
+
#include "ResponseCode.h"
#include "SecondaryTableController.h"
@@ -132,7 +134,7 @@ int SecondaryTableController::runAndFree(SocketClient *cli, char *cmd) {
free(cmd);
return -1;
}
- ret = system(cmd);
+ ret = system_nosh(cmd);
free(cmd);
return ret;
}
diff --git a/ThrottleController.cpp b/ThrottleController.cpp
index c7dfad8f..1ae31b84 100644
--- a/ThrottleController.cpp
+++ b/ThrottleController.cpp
@@ -36,7 +36,7 @@
static char TC_PATH[] = "/system/bin/tc";
-extern "C" int logwrap(int argc, const char **argv, int background);
+extern "C" int system_nosh(const char *command);
extern "C" int ifc_init(void);
extern "C" int ifc_up(const char *name);
extern "C" int ifc_down(const char *name);
@@ -53,7 +53,7 @@ int ThrottleController::runTcCmd(const char *cmd) {
}
asprintf(&buffer, "%s %s", TC_PATH, cmd);
- res = system(buffer);
+ res = system_nosh(buffer);
free(buffer);
return res;
}
diff --git a/logwrapper.c b/logwrapper.c
index 739f141b..d9913f27 100644
--- a/logwrapper.c
+++ b/logwrapper.c
@@ -175,3 +175,66 @@ int logwrap(int argc, const char* argv[], int background)
return 0;
}
+
+/*
+ * The following is based off of bionic/libc/unistd/system.c with
+ * modifications to avoid calling /system/bin/sh -c
+ */
+extern char **environ;
+int system_nosh(const char *command)
+{
+ pid_t pid;
+ sig_t intsave, quitsave;
+ sigset_t mask, omask;
+ int pstat;
+ char buffer[255];
+ char *argp[32];
+ char *next = buffer;
+ char *tmp;
+ int i = 0;
+
+ if (!command) /* just checking... */
+ return(1);
+
+ /*
+ * The command to argp splitting is from code that was
+ * reverted in Change: 11b4e9b2
+ */
+ if (strnlen(buffer, sizeof(buffer) - 1) == sizeof(buffer) - 1) {
+ LOGE("command line too long while processing: %s", command);
+ errno = E2BIG;
+ return -1;
+ }
+ strcpy(buffer, command); // Command len is already checked.
+ while ((tmp = strsep(&next, " "))) {
+ argp[i++] = tmp;
+ if (i == 32) {
+ LOGE("argument overflow while processing: %s", command);
+ errno = E2BIG;
+ return -1;
+ }
+ }
+ argp[i] = NULL;
+
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &mask, &omask);
+ switch (pid = vfork()) {
+ case -1: /* error */
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ return(-1);
+ case 0: /* child */
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ execve(argp[0], argp, environ);
+ _exit(127);
+ }
+
+ intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN);
+ quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
+ pid = waitpid(pid, (int *)&pstat, 0);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ (void)bsd_signal(SIGINT, intsave);
+ (void)bsd_signal(SIGQUIT, quitsave);
+ return (pid == -1 ? -1 : pstat);
+}