mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-31 22:35:10 +00:00
Change intercept IPC to use a localhost socket instead of inherited fd.
This allows intercept mode to work with shells that close all open fds upon startup. The ctor in sudo_intercept.so requests the port number and secret over the socket inherited from the parent then closes it. For each policy request, a TCP connection is made to the sudo parent process to perform the policy check. Child processes re-use the TCP socket to request the port number and secret just like the initial process started by sudo does.
This commit is contained in:
@@ -47,7 +47,6 @@
|
||||
#include "sudo_exec.h"
|
||||
#include "sudo_plugin.h"
|
||||
#include "sudo_plugin_int.h"
|
||||
#include "sudo_rand.h"
|
||||
|
||||
/* Evaluates to true if the event has /dev/tty as its fd. */
|
||||
#define USERTTY_EVENT(_ev) (sudo_ev_get_fd((_ev)) == io_fds[SFD_USERTTY])
|
||||
@@ -62,14 +61,11 @@ struct monitor_message {
|
||||
};
|
||||
TAILQ_HEAD(monitor_message_list, monitor_message);
|
||||
|
||||
/* Note that details and evbase must come first. */
|
||||
struct exec_closure_pty {
|
||||
uint64_t secret;
|
||||
struct command_details *details;
|
||||
struct sudo_event_base *evbase;
|
||||
struct sudo_event *backchannel_event;
|
||||
struct sudo_event *fwdchannel_event;
|
||||
struct sudo_event *intercept_event;
|
||||
struct sudo_event *sigint_event;
|
||||
struct sudo_event *sigquit_event;
|
||||
struct sudo_event *sigtstp_event;
|
||||
@@ -1207,13 +1203,11 @@ fwdchannel_cb(int sock, int what, void *v)
|
||||
*/
|
||||
static void
|
||||
fill_exec_closure_pty(struct exec_closure_pty *ec, struct command_status *cstat,
|
||||
struct command_details *details, pid_t ppgrp, int backchannel,
|
||||
int intercept_fd)
|
||||
struct command_details *details, pid_t ppgrp, int backchannel)
|
||||
{
|
||||
debug_decl(fill_exec_closure_pty, SUDO_DEBUG_EXEC);
|
||||
|
||||
/* Fill in the non-event part of the closure. */
|
||||
ec->secret = arc4random() | ((uint64_t)arc4random() << 32);
|
||||
ec->cmnd_pid = -1;
|
||||
ec->ppgrp = ppgrp;
|
||||
ec->cstat = cstat;
|
||||
@@ -1239,17 +1233,6 @@ fill_exec_closure_pty(struct exec_closure_pty *ec, struct command_status *cstat,
|
||||
sudo_fatal("%s", U_("unable to add event to queue"));
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "backchannel fd %d\n", backchannel);
|
||||
|
||||
/* Event for sudo_intercept.so (optional). */
|
||||
if (intercept_fd != -1) {
|
||||
ec->intercept_event = sudo_ev_alloc(intercept_fd,
|
||||
SUDO_EV_READ|SUDO_EV_PERSIST, intercept_fd_cb, ec);
|
||||
if (ec->intercept_event == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
if (sudo_ev_add(ec->evbase, ec->intercept_event, NULL, false) == -1)
|
||||
sudo_fatal("%s", U_("unable to add event to queue"));
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "intercept fd %d\n", intercept_fd);
|
||||
}
|
||||
|
||||
/* Events for local signals. */
|
||||
ec->sigint_event = sudo_ev_alloc(SIGINT,
|
||||
SUDO_EV_SIGINFO, signal_cb_pty, ec);
|
||||
@@ -1409,7 +1392,7 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
||||
* This must be inherited across exec, hence no FD_CLOEXEC.
|
||||
*/
|
||||
if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_CHILDREN)) {
|
||||
if (socketpair(PF_UNIX, SOCK_DGRAM, 0, intercept_sv) == -1)
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, intercept_sv) == -1)
|
||||
sudo_fatal("%s", U_("unable to create sockets"));
|
||||
}
|
||||
|
||||
@@ -1652,7 +1635,13 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
||||
* Fill in exec closure, allocate event base, signal events and
|
||||
* the backchannel event.
|
||||
*/
|
||||
fill_exec_closure_pty(&ec, cstat, details, ppgrp, sv[0], intercept_sv[0]);
|
||||
fill_exec_closure_pty(&ec, cstat, details, ppgrp, sv[0]);
|
||||
|
||||
/* Create event and closure for intercept mode. */
|
||||
if (intercept_sv[0] != -1) {
|
||||
if (!intercept_setup(intercept_sv[0], ec.evbase, details))
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Restore signal mask now that signal handlers are setup. */
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
|
Reference in New Issue
Block a user