From c9dd84fac29bc16ecdbb1c9181b2aae2cd52e08f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 19 Nov 2014 21:22:31 +1100 Subject: [PATCH 1/4] Handle invalidated socket fds with an error in the wait read/write select functions --- src/libckpool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libckpool.c b/src/libckpool.c index 8fb55173..747ac02d 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -711,6 +711,8 @@ int wait_read_select(int sockd, int timeout) { struct pollfd sfd; + if (unlikely(sockd < 0)) + return -1; sfd.fd = sockd; sfd.events = POLLIN; sfd.revents = 0; @@ -784,6 +786,8 @@ int wait_write_select(int sockd, int timeout) { struct pollfd sfd; + if (unlikely(sockd < 0)) + return -1; sfd.fd = sockd; sfd.events = POLLOUT; sfd.revents = 0; From 06507de1fcf8aec776ab3e5f1a711a6442ea7ecf Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 19 Nov 2014 21:25:33 +1100 Subject: [PATCH 2/4] Handle read and write_length functions receiving an invalidated fd --- src/libckpool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libckpool.c b/src/libckpool.c index 747ac02d..860b537e 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -728,6 +728,8 @@ int read_length(int sockd, void *buf, int len) LOGWARNING("Invalid read length of %d requested in read_length", len); return -1; } + if (unlikely(sockd < 0)) + return -1; while (len) { ret = recv(sockd, buf + ofs, len, MSG_WAITALL); if (unlikely(ret < 1)) @@ -803,6 +805,8 @@ int write_length(int sockd, const void *buf, int len) LOGWARNING("Invalid write length of %d requested in write_length", len); return -1; } + if (unlikely(sockd < 0)) + return -1; while (len) { ret = write(sockd, buf + ofs, len); if (unlikely(ret < 0)) From 61300493e79a206d82d4633e0e69cfca69675153 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 19 Nov 2014 21:29:18 +1100 Subject: [PATCH 3/4] Empty buffers of servers and proxy when killing them --- src/ckpool.h | 1 + src/generator.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/ckpool.h b/src/ckpool.h index d246e97f..6c7743a2 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -188,6 +188,7 @@ bool ckmsgq_empty(ckmsgq_t *ckmsgq); ckpool_t *global_ckp; bool ping_main(ckpool_t *ckp); +void empty_buffer(connsock_t *cs); int read_socket_line(connsock_t *cs, int timeout); bool _send_proc(proc_instance_t *pi, const char *msg, const char *file, const char *func, const int line); #define send_proc(pi, msg) _send_proc(pi, msg, __FILE__, __func__, __LINE__) diff --git a/src/generator.c b/src/generator.c index f9791257..0fd73d55 100644 --- a/src/generator.c +++ b/src/generator.c @@ -225,6 +225,7 @@ static void kill_server(server_instance_t *si) LOGNOTICE("Killing server"); cs = &si->cs; Close(cs->fd); + empty_buffer(cs); dealloc(cs->url); dealloc(cs->port); dealloc(cs->auth); @@ -1428,6 +1429,7 @@ static void kill_proxy(ckpool_t *ckp, proxy_instance_t *proxi) LOGNOTICE("Killing proxy"); cs = proxi->cs; Close(cs->fd); + empty_buffer(cs); /* All our notify data is invalid if we reconnect so discard them */ mutex_lock(&proxi->notify_lock); From 1d0d914d52e7d46fcb2836d6703159be004542f2 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 19 Nov 2014 21:34:40 +1100 Subject: [PATCH 4/4] Store the fd in read_socket_line to not have it change under us, and empty the cs buffer on failure --- src/ckpool.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ckpool.c b/src/ckpool.c index e1d1186b..abff3050 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -367,11 +367,11 @@ void empty_buffer(connsock_t *cs) * of the buffer for use on the next receive. */ int read_socket_line(connsock_t *cs, int timeout) { + int fd = cs->fd, ret = -1; char *eom = NULL; size_t buflen; - int ret = -1; - if (unlikely(cs->fd < 0)) + if (unlikely(fd < 0)) goto out; if (unlikely(!cs->buf)) @@ -388,7 +388,7 @@ int read_socket_line(connsock_t *cs, int timeout) while (42) { char readbuf[PAGESIZE] = {}; - ret = wait_read_select(cs->fd, eom ? 0 : timeout); + ret = wait_read_select(fd, eom ? 0 : timeout); if (eom && !ret) break; if (ret < 1) { @@ -398,7 +398,7 @@ int read_socket_line(connsock_t *cs, int timeout) LOGERR("Select failed in read_socket_line"); goto out; } - ret = recv(cs->fd, readbuf, PAGESIZE - 4, 0); + ret = recv(fd, readbuf, PAGESIZE - 4, 0); if (ret < 1) { LOGERR("Failed to recv in read_socket_line"); ret = -1; @@ -423,6 +423,7 @@ int read_socket_line(connsock_t *cs, int timeout) *eom = '\0'; out: if (ret < 0) { + empty_buffer(cs); dealloc(cs->buf); Close(cs->fd); }