diff --git a/src/ckpool.c b/src/ckpool.c index 2dd7cd3e..5fcc7c9b 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -510,6 +510,8 @@ bool ping_main(ckpool_t *ckp) void empty_buffer(connsock_t *cs) { + if (cs->buf) + cs->buf[0] = '\0'; cs->buflen = cs->bufofs = 0; } @@ -557,11 +559,15 @@ static int read_cs_length(connsock_t *cs, float *timeout, int len) while (cs->bufofs < len) { char readbuf[PAGESIZE]; + int readlen; ret = wait_read_select(cs->fd, *timeout); if (ret < 1) goto out; - ret = recv(cs->fd, readbuf, len - cs->buflen, MSG_DONTWAIT); + readlen = len - cs->buflen; + if (readlen >= PAGESIZE) + readlen = PAGESIZE - 4; + ret = recv(cs->fd, readbuf, readlen, MSG_DONTWAIT); if (ret < 1) goto out; add_bufline(cs, readbuf, ret); @@ -617,8 +623,8 @@ static int read_gz_line(connsock_t *cs, float *timeout) clear_bufline(cs); /* Do decompresion and buffer reconstruction here */ - dest = ckalloc(decompsize); - res = decompsize; + res = round_up_page(decompsize); + dest = ckalloc(res); ret = uncompress((Bytef *)dest, &res, (Bytef *)cs->buf, compsize); if (ret != Z_OK || res != decompsize) { @@ -736,7 +742,7 @@ out: if (ret < 0) { empty_buffer(cs); dealloc(cs->buf); - } else if (cs->buflen && !strncmp(cs->buf, gzip_magic, 3)) + } else if (ret == 3 && !strncmp(cs->buf, gzip_magic, 3)) ret = read_gz_line(cs, timeout); return ret; } diff --git a/src/connector.c b/src/connector.c index 2a9500cf..5593476b 100644 --- a/src/connector.c +++ b/src/connector.c @@ -491,7 +491,12 @@ compressed: if (client->bufofs < client->compsize) goto retry; - res = client->decompsize; + res = PAGESIZE - 4; + if (unlikely(client->decompsize > res)) { + LOGNOTICE("Client attempting to send oversize compressed message, disconnecting"); + invalidate_client(ckp, cdata, client); + return; + } ret = uncompress((Bytef *)msg, &res, (Bytef *)client->buf, client->compsize); if (ret != Z_OK || res != client->decompsize) { LOGNOTICE("Failed to decompress %lu from %lu bytes in parse_client_msg, got %d", @@ -1003,7 +1008,7 @@ static void send_client(cdata_t *cdata, const int64_t id, char *buf) /* Does this client accept compressed data? Only compress if it's * larger than one MTU. */ - if (client->gz && len > 1492) { + if (client->gz) { unsigned long compsize, decompsize = len; uint32_t msglen; char *dest;