Really fix flushing of data in client_close().

Now that we call fmt_exit_message() from client_close() we do not
need to try to determine whether the read or write events were
pending in the old base.

We can't tell anyway because the active flag in the event was cleared
when the old sudo event base was destroyed.  It is correct to enable
both the read and write events after formatting the ExitMessage.
This commit is contained in:
Todd C. Miller
2020-01-15 14:47:42 -07:00
parent bbb9520c3a
commit 161750fc56
2 changed files with 26 additions and 25 deletions

View File

@@ -845,6 +845,9 @@ sudo_ev_pending_v1(struct sudo_event *ev, short events, struct timespec *ts)
int ret = 0;
debug_decl(sudo_ev_pending, SUDO_DEBUG_EVENT);
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: event %p, flags 0x%x, events 0x%x",
__func__, ev, ev->flags, ev->events);
if (!ISSET(ev->flags, SUDO_EVQ_INSERTED))
debug_return_int(0);

View File

@@ -1396,13 +1396,16 @@ bool
client_close(struct client_closure *closure, int exit_status, int error)
{
struct sudo_event_base *evbase = NULL;
short events;
bool ret = false;
debug_decl(client_close, SUDOERS_DEBUG_UTIL);
if (closure->disabled)
goto done;
/* Format and append an ExitMessage to the write queue. */
if (!fmt_exit_message(closure, exit_status, error))
goto done;
/*
* Create private event base and reparent the read/write events.
* We cannot use the main sudo event loop as it has already exited.
@@ -1412,36 +1415,31 @@ client_close(struct client_closure *closure, int exit_status, int error)
goto done;
}
events = closure->read_ev->pending(closure->read_ev, SUDO_PLUGIN_EV_READ,
NULL);
/* Enable read event to receive server messages. */
closure->read_ev->setbase(closure->read_ev, evbase);
if (events == SUDO_PLUGIN_EV_READ) {
if (closure->read_ev->add(closure->read_ev,
&closure->log_details->server_timeout) == -1) {
sudo_warn(U_("unable to add event to queue"));
goto done;
}
}
events = closure->write_ev->pending(closure->write_ev, SUDO_PLUGIN_EV_WRITE,
NULL);
closure->write_ev->setbase(closure->write_ev, evbase);
if (events == SUDO_PLUGIN_EV_WRITE) {
if (closure->write_ev->add(closure->write_ev,
&closure->log_details->server_timeout) == -1) {
sudo_warn(U_("unable to add event to queue"));
goto done;
}
}
/* Format and append an ExitMessage to the write queue. */
if (!fmt_exit_message(closure, exit_status, error))
if (closure->read_ev->add(closure->read_ev,
&closure->log_details->server_timeout) == -1) {
sudo_warn(U_("unable to add event to queue"));
goto done;
}
/* Enable the write event to write the ExitMessage. */
closure->write_ev->setbase(closure->write_ev, evbase);
if (closure->write_ev->add(closure->write_ev,
&closure->log_details->server_timeout) == -1) {
sudo_warn(U_("unable to add event to queue"));
goto done;
}
/* Loop until queues are flushed and final commit point received. */
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"flushing buffers and waiting for final commit point");
ret = sudo_ev_dispatch(evbase) == 0;
if (sudo_ev_dispatch(evbase) == -1 || sudo_ev_got_break(evbase)) {
sudo_warnx(U_("error in event loop"));
goto done;
}
ret = true;
done:
sudo_ev_base_free(evbase);