diff options
author | JP Abgrall <jpa@google.com> | 2011-12-14 15:20:59 -0800 |
---|---|---|
committer | The Android Automerger <android-build@android.com> | 2011-12-14 15:44:43 -0800 |
commit | 8a12dd0851cc2aaa1f6ffb27e5d7616733200c36 (patch) | |
tree | 3f77f052986e5e1c54dc2dddc280c05af7b8ada7 | |
parent | 063af322b48ab1bb0c3e09eb0b64915ba568275b (diff) | |
download | netd-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.cpp | 3 | ||||
-rw-r--r-- | NatController.cpp | 4 | ||||
-rw-r--r-- | SecondaryTableController.cpp | 4 | ||||
-rw-r--r-- | ThrottleController.cpp | 4 | ||||
-rw-r--r-- | logwrapper.c | 63 |
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); +} |