diff options
author | toni <matzeton@googlemail.com> | 2017-01-06 17:56:43 +0100 |
---|---|---|
committer | toni <matzeton@googlemail.com> | 2017-01-06 17:56:43 +0100 |
commit | eb05457fdc59b2dceca5a09e3572e424008a8b66 (patch) | |
tree | f83f2a5cc831ae0afd8a61b1937e507f26ee7f9b | |
parent | e6541524a01d1497349e1ed641e08b503f092eba (diff) |
using safe_exec instead of very unsafe system func
-rw-r--r-- | suidcmd.c | 45 |
1 files changed, 43 insertions, 2 deletions
@@ -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; } |