aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoni <matzeton@googlemail.com>2017-01-06 17:56:43 +0100
committertoni <matzeton@googlemail.com>2017-01-06 17:56:43 +0100
commiteb05457fdc59b2dceca5a09e3572e424008a8b66 (patch)
treef83f2a5cc831ae0afd8a61b1937e507f26ee7f9b
parente6541524a01d1497349e1ed641e08b503f092eba (diff)
using safe_exec instead of very unsafe system func
-rw-r--r--suidcmd.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/suidcmd.c b/suidcmd.c
index 0998f41..7244106 100644
--- a/suidcmd.c
+++ b/suidcmd.c
@@ -6,12 +6,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
#ifndef CMD
#define CMD "/usr/sbin/ether-wake"
#endif
+
+int safe_exec(const char* cmdWithArgs)
+{
+ pid_t child;
+ if ( (child = fork()) == 0 ) {
+ size_t szCur = 0, szMax = 10;
+ char** args = calloc(szMax, sizeof(char**));
+ const char* cmd = NULL;
+
+ const char* prv = cmdWithArgs;
+ const char* cur = NULL;
+ while ( (cur = strchr(prv, ' ')) ) {
+ if (cmd == NULL)
+ cmd = strndup(prv, cur-prv);
+
+ args[szCur++] = strndup(prv, cur-prv);
+ if (szCur >= szMax) {
+ szMax *= 2;
+ args = realloc(args, sizeof(char**)*szMax);
+ }
+
+ cur++;
+ prv = cur;
+ }
+ if (cmd == NULL) {
+ cmd = cmdWithArgs;
+ } else {
+ args[szCur++] = strndup(prv, cur-prv);
+ }
+ args[szCur] = NULL;
+ execv(cmd, args);
+ } else {
+ int retval = 0;
+ waitpid(child, &retval, 0);
+ return retval;
+ }
+ return -1;
+}
+
int main(int argc, char** argv)
{
uid_t ruid, euid, suid;
@@ -42,13 +83,13 @@ int main(int argc, char** argv)
free(prev_cmd);
}
- printf("system(\"%s\")\n", cmd);
int retval = -1;
- switch ( (retval = system(cmd)) ) {
+ switch ( (retval = safe_exec(cmd)) ) {
case -1: fprintf(stderr, "%s: could not create child process..\n", argv[0]); return 1;
case 127: fprintf(stderr, "%s: could not execute shell (child process)..\n", argv[0]); return 1;
default:
printf("%s: child process returned with: %d\n", argv[0], retval);
}
+ free(cmd);
return 0;
}