diff --git a/src/exec_intercept.c b/src/exec_intercept.c index d9777ef1a..9b7965abe 100644 --- a/src/exec_intercept.c +++ b/src/exec_intercept.c @@ -81,6 +81,7 @@ struct intercept_closure { static union sudo_token_un intercept_token; static in_port_t intercept_listen_port; +static struct intercept_closure *accept_closure; static void intercept_accept_cb(int fd, int what, void *v); static void intercept_cb(int fd, int what, void *v); @@ -128,8 +129,9 @@ bad: * the connection. */ static void -intercept_connection_close(int fd, struct intercept_closure *closure) +intercept_connection_close(struct intercept_closure *closure) { + const int fd = sudo_ev_get_fd(&closure->ev); size_t n; debug_decl(intercept_connection_close, SUDO_DEBUG_EXEC); @@ -155,6 +157,19 @@ intercept_connection_close(int fd, struct intercept_closure *closure) debug_return; } +void +intercept_cleanup(void) +{ + debug_decl(intercept_cleanup, SUDO_DEBUG_EXEC); + + if (accept_closure != NULL) { + intercept_connection_close(accept_closure); + accept_closure = NULL; + } + + debug_return; +} + /* * Prepare to listen on localhost using an ephemeral port. * Sets intercept_token and intercept_listen_port as side effects. @@ -848,6 +863,7 @@ intercept_write(int fd, struct intercept_closure *closure) } closure->listen_sock = -1; closure->state = RECV_CONNECTION; + accept_closure = closure; break; case POLICY_ACCEPT: /* Re-use event to read InterceptHello from sudo_intercept.so ctor. */ @@ -864,7 +880,7 @@ intercept_write(int fd, struct intercept_closure *closure) break; default: /* Done with this connection. */ - intercept_connection_close(fd, closure); + intercept_connection_close(closure); } ret = true; @@ -893,7 +909,7 @@ intercept_cb(int fd, int what, void *v) } if (!success) - intercept_connection_close(fd, closure); + intercept_connection_close(closure); debug_return; } @@ -916,7 +932,8 @@ intercept_accept_cb(int fd, int what, void *v) sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "state mismatch, expected RECV_CONNECTION (%d), got %d", RECV_CONNECTION, closure->state); - intercept_connection_close(fd, closure); + intercept_connection_close(closure); + accept_closure = NULL; debug_return; } diff --git a/src/exec_nopty.c b/src/exec_nopty.c index 0bfb2fe68..b11916602 100644 --- a/src/exec_nopty.c +++ b/src/exec_nopty.c @@ -322,6 +322,9 @@ free_exec_closure_nopty(struct exec_closure_nopty *ec) { debug_decl(free_exec_closure_nopty, SUDO_DEBUG_EXEC); + /* Free any remaining intercept resources. */ + intercept_cleanup(); + sudo_ev_base_free(ec->evbase); sudo_ev_free(ec->errpipe_event); sudo_ev_free(ec->sigint_event); diff --git a/src/exec_pty.c b/src/exec_pty.c index e864d3672..bba7c49cd 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -1325,6 +1325,9 @@ free_exec_closure_pty(struct exec_closure_pty *ec) struct monitor_message *msg; debug_decl(free_exec_closure_pty, SUDO_DEBUG_EXEC); + /* Free any remaining intercept resources. */ + intercept_cleanup(); + sudo_ev_base_free(ec->evbase); sudo_ev_free(ec->backchannel_event); sudo_ev_free(ec->fwdchannel_event); diff --git a/src/sudo_exec.h b/src/sudo_exec.h index 47419f3ec..ac4de791f 100644 --- a/src/sudo_exec.h +++ b/src/sudo_exec.h @@ -110,6 +110,7 @@ char **enable_monitor(char *envp[], const char *dso); /* exec_intercept.c */ bool intercept_setup(int fd, struct sudo_event_base *evbase, struct command_details *details); +void intercept_cleanup(void); /* exec_nopty.c */ void exec_nopty(struct command_details *details, struct command_status *cstat);