diff options
Diffstat (limited to 'suidcmd.c')
-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; } |