]> granicus.if.org Git - sudo/commitdiff
Return an error from selinux_setup() instead of exiting.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 8 Jun 2010 22:12:59 +0000 (18:12 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 8 Jun 2010 22:12:59 +0000 (18:12 -0400)
Call selinux_setup() from exec_setup().

--HG--
branch : 1.7

exec.c
exec_pty.c
selinux.c
sudo.c
sudo.h

diff --git a/exec.c b/exec.c
index 6c0ae4c2a146c6429e62314d4efef63128af4221..c8a38546ef5958e7ce8d2814a72613b53fe17e89 100644 (file)
--- 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;
index aefdd75b2d08c452eeb2002da90103a3a253410a..7c2940fda9d337cbbfa36e0a82818dd2af3c348e 100644 (file)
@@ -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]);
index 12c8d3e07124ef203b85e2a9325aee4ea202f71c..a423aa9c79dbf61bdf3b754cf552dfac80d9682d 100644 (file)
--- 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 f3a05be0cc3988f5a2dc3a42665824e3c7957dd9..c9b1d9acfb4ac13eb5dfd662e3bec0b441ac85ae 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -92,9 +92,6 @@
 # include <project.h>
 # include <sys/task.h>
 #endif
-#ifdef HAVE_SELINUX
-# include <selinux/selinux.h>
-#endif
 #ifdef HAVE_MBR_CHECK_MEMBERSHIP
 # include <membership.h>
 #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 e9ea962172be750b0e72e88264afcfd802aac670..059dcd4381215b57c9e7bc6ce7e77871e1b552ec 100644 (file)
--- 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));