Add fallback to /bin/sh when execve() fails with ENOEXEC.

This commit is contained in:
Todd C. Miller
2010-02-28 15:10:18 -05:00
parent 76c90bc301
commit 19b17c7502

View File

@@ -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