Refactor disable_execute() and my_execve() into exec_common.c for

use by sesh.c.  This fixes NOEXEC when SELinux is used.  Instead
of disabling exec in exec_setup(), disable it immediately before
executing the command.  Adapted from a diff by Arno Schuring.
This commit is contained in:
Todd C. Miller
2012-01-25 14:58:02 -05:00
parent e852bf4374
commit d11e7febbc
10 changed files with 240 additions and 140 deletions

View File

@@ -82,30 +82,6 @@ static void schedule_signal(int signo);
static void handler_nofwd(int s, siginfo_t *info, void *context);
#endif
/*
* Like execve(2) but falls back to running through /bin/sh
* ala execvp(3) if we get ENOEXEC.
*/
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);
efree(nargv);
}
return -1;
}
/*
* Fork and execute a command, returns the child's pid.
* Sends errno back on sv[1] if execve() fails.
@@ -149,11 +125,15 @@ static int fork_cmnd(struct command_details *details, int sv[2])
closefrom(maxfd);
}
#ifdef HAVE_SELINUX
if (ISSET(details->flags, CD_RBAC_ENABLED))
selinux_execve(details->command, details->argv, details->envp);
else
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
selinux_execve(details->command, details->argv, details->envp,
ISSET(details->flags, CD_NOEXEC));
} else
#endif
my_execve(details->command, details->argv, details->envp);
{
sudo_execve(details->command, details->argv, details->envp,
ISSET(details->flags, CD_NOEXEC));
}
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
details->command, strerror(errno));
}
@@ -222,7 +202,7 @@ restore_signals(void)
* we fact that we have two different controlling terminals to deal with.
*/
int
sudo_execve(struct command_details *details, struct command_status *cstat)
sudo_execute(struct command_details *details, struct command_status *cstat)
{
int maxfd, n, nready, sv[2];
const char *utmp_user = NULL;
@@ -230,7 +210,7 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
fd_set *fdsr, *fdsw;
sigaction_t sa;
pid_t child;
debug_decl(sudo_execve, SUDO_DEBUG_EXEC)
debug_decl(sudo_execute, SUDO_DEBUG_EXEC)
/* If running in background mode, fork and exit. */
if (ISSET(details->flags, CD_BACKGROUND)) {