control: Abort control recv path on hangup

This fixes a crash when we try and re-use it in another function.
This commit is contained in:
Roy Marples 2023-11-13 10:24:15 +00:00
parent 21d020b00e
commit 3b4c71859c

View File

@ -106,7 +106,7 @@ control_hangup(struct fd_list *fd)
control_free(fd); control_free(fd);
} }
static void static int
control_handle_read(struct fd_list *fd) control_handle_read(struct fd_list *fd)
{ {
char buffer[1024]; char buffer[1024];
@ -117,7 +117,7 @@ control_handle_read(struct fd_list *fd)
logerr(__func__); logerr(__func__);
if (bytes == -1 || bytes == 0) { if (bytes == -1 || bytes == 0) {
control_hangup(fd); control_hangup(fd);
return; return -1;
} }
#ifdef PRIVSEP #ifdef PRIVSEP
@ -129,21 +129,23 @@ control_handle_read(struct fd_list *fd)
fd->flags &= ~FD_SENDLEN; fd->flags &= ~FD_SENDLEN;
if (err == -1) { if (err == -1) {
logerr(__func__); logerr(__func__);
return; return 0;
} }
if (err == 1 && if (err == 1 &&
ps_ctl_sendargs(fd, buffer, (size_t)bytes) == -1) { ps_ctl_sendargs(fd, buffer, (size_t)bytes) == -1) {
logerr(__func__); logerr(__func__);
control_free(fd); control_free(fd);
return -1;
} }
return; return 0;
} }
#endif #endif
control_recvdata(fd, buffer, (size_t)bytes); control_recvdata(fd, buffer, (size_t)bytes);
return 0;
} }
static void static int
control_handle_write(struct fd_list *fd) control_handle_write(struct fd_list *fd)
{ {
struct iovec iov[2]; struct iovec iov[2];
@ -170,7 +172,7 @@ control_handle_write(struct fd_list *fd)
logerr("%s: write", __func__); logerr("%s: write", __func__);
} }
control_hangup(fd); control_hangup(fd);
return; return -1;
} }
TAILQ_REMOVE(&fd->queue, data, next); TAILQ_REMOVE(&fd->queue, data, next);
@ -183,7 +185,7 @@ control_handle_write(struct fd_list *fd)
#endif #endif
if (TAILQ_FIRST(&fd->queue) != NULL) if (TAILQ_FIRST(&fd->queue) != NULL)
return; return 0;
#ifdef PRIVSEP #ifdef PRIVSEP
if (IN_PRIVSEP_SE(fd->ctx) && !(fd->flags & FD_LISTEN)) { if (IN_PRIVSEP_SE(fd->ctx) && !(fd->flags & FD_LISTEN)) {
@ -196,9 +198,9 @@ control_handle_write(struct fd_list *fd)
if (eloop_event_add(fd->ctx->eloop, fd->fd, ELE_READ, if (eloop_event_add(fd->ctx->eloop, fd->fd, ELE_READ,
control_handle_data, fd) == -1) control_handle_data, fd) == -1)
logerr("%s: eloop_event_add", __func__); logerr("%s: eloop_event_add", __func__);
return 0;
} }
static void static void
control_handle_data(void *arg, unsigned short events) control_handle_data(void *arg, unsigned short events)
{ {
@ -207,10 +209,14 @@ control_handle_data(void *arg, unsigned short events)
if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP))) if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP)))
logerrx("%s: unexpected event 0x%04x", __func__, events); logerrx("%s: unexpected event 0x%04x", __func__, events);
if (events & ELE_WRITE && !(events & ELE_HANGUP)) if (events & ELE_WRITE && !(events & ELE_HANGUP)) {
control_handle_write(fd); if (control_handle_write(fd) == -1)
if (events & ELE_READ) return;
control_handle_read(fd); }
if (events & ELE_READ) {
if (control_handle_read(fd) == -1)
return;
}
if (events & ELE_HANGUP) if (events & ELE_HANGUP)
control_hangup(fd); control_hangup(fd);
} }