--- embedaddon/sudo/src/selinux.c 2012/02/21 16:23:02 1.1 +++ embedaddon/sudo/src/selinux.c 2012/05/29 12:26:49 1.1.1.2 @@ -48,6 +48,7 @@ #endif #include "sudo.h" +#include "sudo_exec.h" static struct selinux_state { security_context_t old_context; @@ -64,8 +65,9 @@ static int audit_role_change(const security_context_t old_context, const security_context_t new_context, const char *ttyn) { - int au_fd, rc; + int au_fd, rc = -1; char *message; + debug_decl(audit_role_change, SUDO_DEBUG_SELINUX) au_fd = audit_open(); if (au_fd == -1) { @@ -73,21 +75,19 @@ audit_role_change(const security_context_t old_context if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT ) error(1, _("unable to open audit system")); - return -1; + } else { + /* audit role change using the same format as newrole(1) */ + easprintf(&message, "newrole: old-context=%s new-context=%s", + old_context, new_context); + rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE, + message, NULL, NULL, ttyn, 1); + if (rc <= 0) + warning(_("unable to send audit message")); + efree(message); + close(au_fd); } - /* audit role change using the same format as newrole(1) */ - easprintf(&message, "newrole: old-context=%s new-context=%s", - old_context, new_context); - rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE, - message, NULL, NULL, ttyn, 1); - if (rc <= 0) - warning(_("unable to send audit message")); - - efree(message); - close(au_fd); - - return rc; + debug_return_int(rc); } #endif @@ -103,6 +103,7 @@ selinux_restore_tty(void) { int retval = 0; security_context_t chk_tty_context = NULL; + debug_decl(selinux_restore_tty, SUDO_DEBUG_SELINUX) if (se_state.ttyfd == -1 || se_state.new_tty_context == NULL) goto skip_relabel; @@ -130,7 +131,7 @@ skip_relabel: freecon(chk_tty_context); chk_tty_context = NULL; } - return retval; + debug_return_int(retval); } /* @@ -147,12 +148,13 @@ relabel_tty(const char *ttyn, int ptyfd) security_context_t tty_con = NULL; security_context_t new_tty_con = NULL; int fd; + debug_decl(relabel_tty, SUDO_DEBUG_SELINUX) se_state.ttyfd = ptyfd; /* It is perfectly legal to have no tty. */ if (ptyfd == -1 && ttyn == NULL) - return 0; + debug_return_int(0); /* If sudo is not allocating a pty for the command, open current tty. */ if (ptyfd == -1) { @@ -222,7 +224,7 @@ relabel_tty(const char *ttyn, int ptyfd) se_state.ttyn = ttyn; se_state.tty_context = tty_con; se_state.new_tty_context = new_tty_con; - return 0; + debug_return_int(0); bad: if (se_state.ttyfd != -1 && se_state.ttyfd != ptyfd) { @@ -230,7 +232,7 @@ bad: se_state.ttyfd = -1; } freecon(tty_con); - return -1; + debug_return_int(-1); } /* @@ -243,18 +245,19 @@ get_exec_context(security_context_t old_context, const security_context_t new_context = NULL; context_t context = NULL; char *typebuf = NULL; + debug_decl(get_exec_context, SUDO_DEBUG_SELINUX) /* We must have a role, the type is optional (we can use the default). */ if (!role) { warningx(_("you must specify a role for type %s"), type); errno = EINVAL; - return NULL; + goto bad; } if (!type) { if (get_default_type(role, &typebuf)) { warningx(_("unable to get default type for role %s"), role); errno = EINVAL; - return NULL; + goto bad; } type = typebuf; } @@ -293,13 +296,13 @@ get_exec_context(security_context_t old_context, const #endif context_free(context); - return new_context; + debug_return_ptr(new_context); bad: - free(typebuf); + efree(typebuf); context_free(context); freecon(new_context); - return NULL; + debug_return_ptr(NULL); } /* @@ -314,6 +317,7 @@ selinux_setup(const char *role, const char *type, cons int ptyfd) { int rval = -1; + debug_decl(selinux_setup, SUDO_DEBUG_SELINUX) /* Store the caller's SID in old_context. */ if (getprevcon(&se_state.old_context)) { @@ -354,40 +358,50 @@ selinux_setup(const char *role, const char *type, cons rval = 0; done: - return rval; + debug_return_int(rval); } void -selinux_execve(const char *path, char *argv[], char *envp[]) +selinux_execve(const char *path, char *const argv[], char *const envp[], + int noexec) { char **nargv; int argc, serrno; + debug_decl(selinux_execve, SUDO_DEBUG_SELINUX) if (setexeccon(se_state.new_context)) { warning(_("unable to set exec context to %s"), se_state.new_context); if (se_state.enforcing) - return; + debug_return; } #ifdef HAVE_SETKEYCREATECON if (setkeycreatecon(se_state.new_context)) { warning(_("unable to set key creation context to %s"), se_state.new_context); if (se_state.enforcing) - return; + debug_return; } #endif /* HAVE_SETKEYCREATECON */ + /* + * Build new argv with sesh as argv[0]. + * If argv[0] ends in -noexec, sesh will disable execute + * for the command it runs. + */ for (argc = 0; argv[argc] != NULL; argc++) continue; - - /* Build new argv with sesh as argv[0]. */ nargv = emalloc2(argc + 2, sizeof(char *)); - nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh"; + if (noexec) + nargv[0] = *argv[0] == '-' ? "-sesh-noexec" : "sesh-noexec"; + else + nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh"; nargv[1] = (char *)path; memcpy(&nargv[2], &argv[1], argc * sizeof(char *)); /* copies NULL */ - execve(_PATH_SUDO_SESH, nargv, envp); + /* sesh will handle noexec for us. */ + sudo_execve(_PATH_SUDO_SESH, nargv, envp, 0); serrno = errno; free(nargv); errno = serrno; + debug_return; }