]> granicus.if.org Git - sudo/commitdiff
If the policy plugin does not provide a close function, there is
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 23 Feb 2013 19:19:07 +0000 (14:19 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 23 Feb 2013 19:19:07 +0000 (14:19 -0500)
no command timeout and no pty is required, skip the event loop and
just exec the command directly.

src/exec.c
src/exec_common.c
src/exec_pty.c
src/sudo_exec.h
src/sudo_plugin_int.h

index 41f7e2f98b2c679c72eb3e8f351981f32696f101..10199c20d6354ccd6cb8524c3634cd015ce6fa49 100644 (file)
@@ -137,35 +137,7 @@ static int fork_cmnd(struct command_details *details, int sv[2])
        close(signal_pipe[0]);
        close(signal_pipe[1]);
        fcntl(sv[1], F_SETFD, FD_CLOEXEC);
-       restore_signals();
-       if (exec_setup(details, NULL, -1) == true) {
-           /* headed for execve() */
-           sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
-               details->argv, details->envp);
-           if (details->closefrom >= 0) {
-               int maxfd = details->closefrom;
-               dup2(sv[1], maxfd);
-               (void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
-               sv[1] = maxfd++;
-               if (sudo_debug_fd_set(maxfd) != -1)
-                   maxfd++;
-               closefrom(maxfd);
-           }
-#ifdef HAVE_SELINUX
-           if (ISSET(details->flags, CD_RBAC_ENABLED)) {
-               selinux_execve(details->command, details->argv, details->envp,
-                   ISSET(details->flags, CD_NOEXEC));
-           } else
-#endif
-           {
-               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));
-       }
-       cstat.type = CMD_ERRNO;
-       cstat.val = errno;
+       exec_cmnd(details, &cstat, &sv[1]);
        send(sv[1], &cstat, sizeof(cstat), 0);
        sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
        _exit(1);
@@ -224,6 +196,11 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
            utmp_user = details->utmp_user ? details->utmp_user : user_details.username;
        sudo_debug_printf(SUDO_DEBUG_INFO, "allocate pty for I/O logging");
        pty_setup(details->euid, user_details.tty, utmp_user);
+    } else if (!ISSET(details->flags, CD_SET_TIMEOUT) &&
+       policy_plugin.u.policy->close == NULL) {
+       /* If no I/O logging, timeout or policy close we can exec directly. */
+       exec_cmnd(details, cstat, NULL);
+       goto done;
     }
 
     /*
@@ -432,7 +409,7 @@ do_tty_io:
        tq_remove(&sigfwd_list, sigfwd);
        efree(sigfwd);
     }
-
+done:
     debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
 }
 
index 045c702de321aa3f3cf263f7875290590c058357..e23b628d1aa089b84f97b20a6c2f2f8201c2c888 100644 (file)
@@ -39,6 +39,7 @@
 # include <priv.h>
 #endif
 #include <errno.h>
+#include <fcntl.h>
 #include <signal.h>
 
 #include "sudo.h"
@@ -156,3 +157,44 @@ sudo_execve(const char *path, char *const argv[], char *const envp[], int noexec
     }
     return -1;
 }
+
+void
+exec_cmnd(struct command_details *details, struct command_status *cstat,
+    int *errfd)
+{
+    debug_decl(exec_cmnd, SUDO_DEBUG_EXEC)
+
+    restore_signals();
+    if (exec_setup(details, NULL, -1) == true) {
+       /* headed for execve() */
+       sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
+           details->argv, details->envp);
+       if (details->closefrom >= 0) {
+           int maxfd = details->closefrom;
+           /* Preserve back channel if present. */
+           if (errfd != NULL) {
+               dup2(*errfd, maxfd);
+               (void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
+               *errfd = maxfd++;
+           }
+           if (sudo_debug_fd_set(maxfd) != -1)
+               maxfd++;
+           closefrom(maxfd);
+       }
+#ifdef HAVE_SELINUX
+       if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+           selinux_execve(details->command, details->argv, details->envp,
+               ISSET(details->flags, CD_NOEXEC));
+       } else
+#endif
+       {
+           sudo_execve(details->command, details->argv, details->envp,
+               ISSET(details->flags, CD_NOEXEC));
+       }
+       cstat->type = CMD_ERRNO;
+       cstat->val = errno;
+       sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
+           details->command, strerror(errno));
+    }
+    debug_return;
+}
index 243012a3359a95a192835552c82ae51ac80254ed..c7cca81320a0eb21f6777cfd17e16ebf1d7d8f6f 100644 (file)
@@ -98,7 +98,8 @@ static struct io_buffer *iobufs;
 
 static void flush_output(void);
 static int exec_monitor(struct command_details *details, int backchannel);
-static void exec_pty(struct command_details *detail, int *errfd);
+static void exec_pty(struct command_details *details,
+    struct command_status *cstat, int *errfd);
 static void sigwinch(int s);
 static void sync_ttysize(int src, int dst);
 static void deliver_signal(pid_t pid, int signo, bool from_parent);
@@ -1077,9 +1078,7 @@ exec_monitor(struct command_details *details, int backchannel)
        restore_signals();
 
        /* setup tty and exec command */
-       exec_pty(details, &errpipe[1]);
-       cstat.type = CMD_ERRNO;
-       cstat.val = errno;
+       exec_pty(details, &cstat, &errpipe[1]);
        ignore_result(write(errpipe[1], &cstat, sizeof(cstat)));
        _exit(1);
     }
@@ -1283,7 +1282,8 @@ flush_output(void)
  * Returns only if execve() fails.
  */
 static void
-exec_pty(struct command_details *details, int *errfd)
+exec_pty(struct command_details *details,
+    struct command_status *cstat, int *errfd)
 {
     pid_t self = getpid();
     debug_decl(exec_pty, SUDO_DEBUG_EXEC);
@@ -1316,30 +1316,9 @@ exec_pty(struct command_details *details, int *errfd)
     if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
        close(io_fds[SFD_STDERR]);
 
-    sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
-       details->argv, details->envp);
-
-    if (details->closefrom >= 0) {
-       int maxfd = details->closefrom;
-       dup2(*errfd, maxfd);
-       (void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
-       *errfd = maxfd++;
-       if (sudo_debug_fd_set(maxfd) != -1)
-           maxfd++;
-       closefrom(maxfd);
-    }
-#ifdef HAVE_SELINUX
-    if (ISSET(details->flags, CD_RBAC_ENABLED)) {
-       selinux_execve(details->command, details->argv, details->envp,
-           ISSET(details->flags, CD_NOEXEC));
-    } else
-#endif
-    {
-       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));
+    /* Execute command; only returns on error. */
+    exec_cmnd(details, cstat, errfd);
+
     debug_return;
 }
 
index ec8450db9bc7b49c9c6e7e82b0fb714049774b66..5a0277cd8c852f7d68a44bf4d469acfe450a17f4 100644 (file)
@@ -54,6 +54,8 @@ struct command_status;
 int fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask);
 int perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat);
 int suspend_parent(int signo);
+void exec_cmnd(struct command_details *details, struct command_status *cstat,
+    int *errfd);
 void fd_set_iobs(fd_set *fdsr, fd_set *fdsw);
 #ifdef SA_SIGINFO
 void handler(int s, siginfo_t *info, void *context);
index aff2344fb401ca7409cfa136741ba3b75dc418a7..bed15c6868f8a4b9a9715207e2a28dd78745c74e 100644 (file)
@@ -97,7 +97,7 @@ struct plugin_container {
 };
 TQ_DECLARE(plugin_container)
 
-extern struct plugin_container_list policy_plugins;
+extern struct plugin_container policy_plugin;
 extern struct plugin_container_list io_plugins;
 
 int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],