mirror of
https://github.com/fluencelabs/redis
synced 2025-06-23 22:11:33 +00:00
Protections against protocol desyncs, leading to infinite query buffer growing, due to nul-terms in specific bytes of the request or indefinitely long multi bulk or bulk count strings without newlines. This bug is related to Issue #141 as well.
This commit is contained in:
@ -1,6 +1,8 @@
|
|||||||
#include "redis.h"
|
#include "redis.h"
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
static void setProtocolError(redisClient *c, int pos);
|
||||||
|
|
||||||
void *dupClientReplyValue(void *o) {
|
void *dupClientReplyValue(void *o) {
|
||||||
incrRefCount((robj*)o);
|
incrRefCount((robj*)o);
|
||||||
return o;
|
return o;
|
||||||
@ -678,8 +680,13 @@ int processInlineBuffer(redisClient *c) {
|
|||||||
size_t querylen;
|
size_t querylen;
|
||||||
|
|
||||||
/* Nothing to do without a \r\n */
|
/* Nothing to do without a \r\n */
|
||||||
if (newline == NULL)
|
if (newline == NULL) {
|
||||||
|
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
|
||||||
|
addReplyError(c,"Protocol error: too big inline request");
|
||||||
|
setProtocolError(c,0);
|
||||||
|
}
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Split the input buffer up to the \r\n */
|
/* Split the input buffer up to the \r\n */
|
||||||
querylen = newline-(c->querybuf);
|
querylen = newline-(c->querybuf);
|
||||||
@ -729,8 +736,13 @@ int processMultibulkBuffer(redisClient *c) {
|
|||||||
|
|
||||||
/* Multi bulk length cannot be read without a \r\n */
|
/* Multi bulk length cannot be read without a \r\n */
|
||||||
newline = strchr(c->querybuf,'\r');
|
newline = strchr(c->querybuf,'\r');
|
||||||
if (newline == NULL)
|
if (newline == NULL) {
|
||||||
|
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
|
||||||
|
addReplyError(c,"Protocol error: too big mbulk count string");
|
||||||
|
setProtocolError(c,0);
|
||||||
|
}
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Buffer should also contain \n */
|
/* Buffer should also contain \n */
|
||||||
if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2))
|
if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2))
|
||||||
@ -764,8 +776,13 @@ int processMultibulkBuffer(redisClient *c) {
|
|||||||
/* Read bulk length if unknown */
|
/* Read bulk length if unknown */
|
||||||
if (c->bulklen == -1) {
|
if (c->bulklen == -1) {
|
||||||
newline = strchr(c->querybuf+pos,'\r');
|
newline = strchr(c->querybuf+pos,'\r');
|
||||||
if (newline == NULL)
|
if (newline == NULL) {
|
||||||
|
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
|
||||||
|
addReplyError(c,"Protocol error: too big bulk count string");
|
||||||
|
setProtocolError(c,0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Buffer should also contain \n */
|
/* Buffer should also contain \n */
|
||||||
if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2))
|
if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2))
|
||||||
@ -806,9 +823,9 @@ int processMultibulkBuffer(redisClient *c) {
|
|||||||
c->querybuf = sdsrange(c->querybuf,pos,-1);
|
c->querybuf = sdsrange(c->querybuf,pos,-1);
|
||||||
|
|
||||||
/* We're done when c->multibulk == 0 */
|
/* We're done when c->multibulk == 0 */
|
||||||
if (c->multibulklen == 0) {
|
if (c->multibulklen == 0) return REDIS_OK;
|
||||||
return REDIS_OK;
|
|
||||||
}
|
/* Still not read to process the command */
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#define REDIS_REQUEST_MAX_SIZE (1024*1024*256) /* max bytes in inline command */
|
#define REDIS_REQUEST_MAX_SIZE (1024*1024*256) /* max bytes in inline command */
|
||||||
#define REDIS_SHARED_INTEGERS 10000
|
#define REDIS_SHARED_INTEGERS 10000
|
||||||
#define REDIS_REPLY_CHUNK_BYTES (5*1500) /* 5 TCP packets with default MTU */
|
#define REDIS_REPLY_CHUNK_BYTES (5*1500) /* 5 TCP packets with default MTU */
|
||||||
|
#define REDIS_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */
|
||||||
#define REDIS_MAX_LOGMSG_LEN 4096 /* Default maximum length of syslog messages */
|
#define REDIS_MAX_LOGMSG_LEN 4096 /* Default maximum length of syslog messages */
|
||||||
#define REDIS_AUTO_AOFREWRITE_PERC 100
|
#define REDIS_AUTO_AOFREWRITE_PERC 100
|
||||||
#define REDIS_AUTO_AOFREWRITE_MIN_SIZE (1024*1024)
|
#define REDIS_AUTO_AOFREWRITE_MIN_SIZE (1024*1024)
|
||||||
|
Reference in New Issue
Block a user