From 7e45964e43a9a64d8f61702b562de4e32d70210f Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 8 Jun 2010 18:12:59 -0400 Subject: [PATCH] Return an error from selinux_setup() instead of exiting. Call selinux_setup() from exec_setup(). --HG-- branch : 1.7 --- exec.c | 8 ++------ exec_pty.c | 6 +----- selinux.c | 40 ++++++++++++++++++++++++++++------------ sudo.c | 15 +++++++++++---- sudo.h | 8 ++++---- 5 files changed, 46 insertions(+), 31 deletions(-) diff --git a/exec.c b/exec.c index 6c0ae4c2a..c8a38546e 100644 --- a/exec.c +++ b/exec.c @@ -123,11 +123,7 @@ static int fork_cmnd(path, argv, envp, sv, rbac_enabled) /* child */ close(sv[0]); fcntl(sv[1], F_SETFD, FD_CLOEXEC); -#ifdef HAVE_SELINUX - if (rbac_enabled) - selinux_setup(user_role, user_type, user_ttypath, -1); -#endif - if (exec_setup(PERM_DOWAIT) == TRUE) { + if (exec_setup(PERM_DOWAIT, rbac_enabled, user_ttypath, -1) == TRUE) { /* headed for execve() */ closefrom(def_closefrom); #ifdef HAVE_SELINUX @@ -187,7 +183,7 @@ sudo_execve(path, argv, envp, uid, cstat, dowait) * If we don't need to wait for the command to finish, just exec it. */ if (!dowait) { - exec_setup(0); + exec_setup(0, FALSE, NULL, -1); closefrom(def_closefrom); my_execve(path, argv, envp); cstat->type = CMD_ERRNO; diff --git a/exec_pty.c b/exec_pty.c index aefdd75b2..7c2940fda 100644 --- a/exec_pty.c +++ b/exec_pty.c @@ -459,11 +459,7 @@ fork_pty(path, argv, envp, sv, rbac_enabled, maxfd) /* child */ close(sv[0]); fcntl(sv[1], F_SETFD, FD_CLOEXEC); -#ifdef HAVE_SELINUX - if (rbac_enabled) - selinux_setup(user_role, user_type, slavename, io_fds[SFD_SLAVE]); -#endif - if (exec_setup(PERM_DOWAIT) == TRUE) { + if (exec_setup(PERM_DOWAIT, rbac_enabled, slavename, io_fds[SFD_SLAVE]) == TRUE) { /* Close the other end of the stdin/stdout/stderr pipes and exec. */ if (io_pipe[STDIN_FILENO][1]) close(io_pipe[STDIN_FILENO][1]); diff --git a/selinux.c b/selinux.c index 12c8d3e07..a423aa9c7 100644 --- a/selinux.c +++ b/selinux.c @@ -205,12 +205,14 @@ get_exec_context(security_context_t old_context, const char *role, const char *t /* We must have a role, the type is optional (we can use the default). */ if (!role) { - warningx("you must specify a role."); + warningx("you must specify a role for type %s", type); + errno = EINVAL; return NULL; } if (!type) { if (get_default_type(role, &typebuf)) { - warningx("unable to get default type"); + warningx("unable to get default type for role %s", role); + errno = EINVAL; return NULL; } type = typebuf; @@ -227,11 +229,11 @@ get_exec_context(security_context_t old_context, const char *role, const char *t * type we will be running the command as. */ if (context_role_set(context, role)) { - warningx("failed to set new role %s", role); + warning("failed to set new role %s", role); goto bad; } if (context_type_set(context, type)) { - warningx("failed to set new type %s", type); + warning("failed to set new type %s", type); goto bad; } @@ -241,6 +243,7 @@ get_exec_context(security_context_t old_context, const char *role, const char *t new_context = estrdup(context_str(context)); if (security_check_context(new_context) < 0) { warningx("%s is not a valid context", new_context); + errno = EINVAL; goto bad; } @@ -263,28 +266,37 @@ bad: * Must run as root, before the uid change. * If ptyfd is not -1, it indicates we are running * in a pty and do not need to reset std{in,out,err}. + * Returns 0 on success and -1 on failure. */ -void +int selinux_setup(const char *role, const char *type, const char *ttyn, int ptyfd) { + int rval = -1; + /* Store the caller's SID in old_context. */ - if (getprevcon(&se_state.old_context)) - error(EXIT_FAILURE, "failed to get old_context"); + if (getprevcon(&se_state.old_context)) { + warning("failed to get old_context"); + goto done; + } se_state.enforcing = security_getenforce(); - if (se_state.enforcing < 0) - error(EXIT_FAILURE, "unable to determine enforcing mode."); + if (se_state.enforcing < 0) { + warning("unable to determine enforcing mode."); + goto done; + } #ifdef DEBUG warningx("your old context was %s", se_state.old_context); #endif se_state.new_context = get_exec_context(se_state.old_context, role, type); if (!se_state.new_context) - error(EXIT_FAILURE, "unable to get exec context"); + goto done; - if (relabel_tty(ttyn, ptyfd) < 0) - error(EXIT_FAILURE, "unable to setup tty context for %s", se_state.new_context); + if (relabel_tty(ttyn, ptyfd) < 0) { + warning("unable to setup tty context for %s", se_state.new_context); + goto done; + } #ifdef DEBUG if (se_state.ttyfd != -1) { @@ -293,6 +305,10 @@ selinux_setup(const char *role, const char *type, const char *ttyn, } #endif + rval = 0; + +done: + return rval; } void diff --git a/sudo.c b/sudo.c index f3a05be0c..c9b1d9acf 100644 --- a/sudo.c +++ b/sudo.c @@ -92,9 +92,6 @@ # include # include #endif -#ifdef HAVE_SELINUX -# include -#endif #ifdef HAVE_MBR_CHECK_MEMBERSHIP # include #endif @@ -808,11 +805,21 @@ set_cmnd(sudo_mode) * Returns TRUE on success and FALSE on failure. */ int -exec_setup(flags) +exec_setup(flags, rbac_enabled, ttyname, ttyfd) int flags; + int rbac_enabled; + const char *ttyname; + int ttyfd; { int rval = FALSE; +#ifdef HAVE_SELINUX + if (rbac_enabled) { + if (selinux_setup(user_role, user_type, ttyname, ttyfd) == -1) + goto done; + } +#endif + /* Close the password and group files and free up memory. */ sudo_endpwent(); sudo_endgrent(); diff --git a/sudo.h b/sudo.h index e9ea96217..059dcd438 100644 --- a/sudo.h +++ b/sudo.h @@ -322,17 +322,17 @@ void sudo_setpwent __P((void)); void sudo_setspent __P((void)); /* selinux.c */ -void selinux_execve __P((const char *path, char *argv[], char *envp[])); -void selinux_setup __P((const char *role, const char *type, const char *ttyn, - int ttyfd)); int selinux_restore_tty __P((void)); +int selinux_setup __P((const char *role, const char *type, const char *ttyn, + int ttyfd)); +void selinux_execve __P((const char *path, char *argv[], char *envp[])); /* set_perms.c */ int set_perms __P((int)); /* sudo.c */ FILE *open_sudoers __P((const char *, int, int *)); -int exec_setup __P((int)); +int exec_setup __P((int, int, const char *, int)); void cleanup __P((int)); void set_fqdn __P((void)); -- 2.40.0