Cluster: sanity checks on the cluster bus message length.
This commit is contained in:
parent
6b9c661838
commit
02796ba7a7
@ -758,20 +758,33 @@ void clusterReadHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
clusterMsg *hdr;
|
clusterMsg *hdr;
|
||||||
clusterLink *link = (clusterLink*) privdata;
|
clusterLink *link = (clusterLink*) privdata;
|
||||||
int readlen;
|
int readlen, rcvbuflen;
|
||||||
REDIS_NOTUSED(el);
|
REDIS_NOTUSED(el);
|
||||||
REDIS_NOTUSED(mask);
|
REDIS_NOTUSED(mask);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (sdslen(link->rcvbuf) >= 4) {
|
rcvbuflen = sdslen(link->rcvbuf);
|
||||||
hdr = (clusterMsg*) link->rcvbuf;
|
if (rcvbuflen < 4) {
|
||||||
readlen = ntohl(hdr->totlen) - sdslen(link->rcvbuf);
|
/* First, obtain the first four bytes to get the full message
|
||||||
|
* length. */
|
||||||
|
readlen = 4 - rcvbuflen;
|
||||||
} else {
|
} else {
|
||||||
readlen = 4 - sdslen(link->rcvbuf);
|
/* Finally read the full message. */
|
||||||
|
hdr = (clusterMsg*) link->rcvbuf;
|
||||||
|
if (rcvbuflen == 4) {
|
||||||
|
/* Perform some sanity check on the message length. */
|
||||||
|
if (ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN) {
|
||||||
|
redisLog(REDIS_WARNING,
|
||||||
|
"Bad message length received from Cluster bus.");
|
||||||
|
handleLinkIOError(link);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readlen = ntohl(hdr->totlen) - rcvbuflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
nread = read(fd,buf,readlen);
|
nread = read(fd,buf,readlen);
|
||||||
if (nread == -1 && errno == EAGAIN) return; /* Just no data */
|
if (nread == -1 && errno == EAGAIN) return; /* No more data ready. */
|
||||||
|
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
/* I/O error... */
|
/* I/O error... */
|
||||||
@ -783,17 +796,19 @@ again:
|
|||||||
/* Read data and recast the pointer to the new buffer. */
|
/* Read data and recast the pointer to the new buffer. */
|
||||||
link->rcvbuf = sdscatlen(link->rcvbuf,buf,nread);
|
link->rcvbuf = sdscatlen(link->rcvbuf,buf,nread);
|
||||||
hdr = (clusterMsg*) link->rcvbuf;
|
hdr = (clusterMsg*) link->rcvbuf;
|
||||||
|
rcvbuflen += nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Total length obtained? read the payload now instead of burning
|
/* Total length obtained? read the payload now instead of burning
|
||||||
* cycles waiting for a new event to fire. */
|
* cycles waiting for a new event to fire. */
|
||||||
if (sdslen(link->rcvbuf) == 4) goto again;
|
if (rcvbuflen == 4) goto again;
|
||||||
|
|
||||||
/* Whole packet in memory? We can process it. */
|
/* Whole packet in memory? We can process it. */
|
||||||
if (sdslen(link->rcvbuf) == ntohl(hdr->totlen)) {
|
if (rcvbuflen == ntohl(hdr->totlen)) {
|
||||||
if (clusterProcessPacket(link)) {
|
if (clusterProcessPacket(link)) {
|
||||||
sdsfree(link->rcvbuf);
|
sdsfree(link->rcvbuf);
|
||||||
link->rcvbuf = sdsempty();
|
link->rcvbuf = sdsempty();
|
||||||
|
rcvbuflen = 0; /* Useless line of code currently... defensive. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -637,6 +637,8 @@ typedef struct {
|
|||||||
union clusterMsgData data;
|
union clusterMsgData data;
|
||||||
} clusterMsg;
|
} clusterMsg;
|
||||||
|
|
||||||
|
#define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg)-sizeof(union clusterMsgData))
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* Global server state
|
* Global server state
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user