From: Todd C. Miller Date: Sun, 28 Feb 2010 20:10:18 +0000 (-0500) Subject: Add fallback to /bin/sh when execve() fails with ENOEXEC. X-Git-Tag: SUDO_1_8_0~853 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=19b17c7502435597c5112771ff2b37f109fdd125;p=sudo Add fallback to /bin/sh when execve() fails with ENOEXEC. --- diff --git a/src/script.c b/src/script.c index 04582db66..287138ec3 100644 --- a/src/script.c +++ b/src/script.c @@ -255,6 +255,29 @@ suspend_parent(int signo, struct script_buf *output) return(rval); } +/* + * Like execve(2) but falls back to running through /bin/sh + * like execvp(3) if we get ENOEXEC. + */ +static int +my_execve(const char *path, char *const argv[], char *const envp[]) +{ + execve(path, argv, envp); + if (errno == ENOEXEC) { + int argc; + char **nargv; + + for (argc = 0; argv[argc] != NULL; argc++) + continue; + nargv = emalloc2(argc + 2, sizeof(char *)); + nargv[0] = "sh"; + nargv[1] = (char *)path; + memcpy(nargv + 2, argv + 1, argc * sizeof(char *)); + execve(_PATH_BSHELL, nargv, envp); + } + return -1; +} + /* * This is a little bit tricky due to how POSIX job control works and * we fact that we have two different controlling terminals to deal with. @@ -391,9 +414,8 @@ script_execve(struct command_details *details, char *argv[], char *envp[], selinux_execve(details->command, argv, envp); else #endif - execve(details->command, argv, envp); + my_execve(details->command, argv, envp); } - /* XXX - fallback to sh */ } cstat->type = CMD_ERRNO; cstat->val = errno; @@ -866,7 +888,7 @@ script_run(const char *path, char *argv[], char *envp[], int rbac_enabled) selinux_execve(path, argv, envp); else #endif - execve(path, argv, envp); + my_execve(path, argv, envp); } static void