Commit 34f447f1 authored by Oran Agra's avatar Oran Agra
Browse files

Fix redis-cli / redis-sential overflow on some platforms (CVE-2021-32762)

The redis-cli command line tool and redis-sentinel service may be vulnerable
to integer overflow when parsing specially crafted large multi-bulk network
replies. This is a result of a vulnerability in the underlying hiredis
library which does not perform an overflow check before calling the calloc()
heap allocation function.

This issue only impacts systems with heap allocators that do not perform their
own overflow checks. Most modern systems do and are therefore not likely to
be affected. Furthermore, by default redis-sentinel uses the jemalloc allocator
which is also not vulnerable.

(cherry picked from commit dbb5d95046e6a415fbd32c721c56e9ea32632898)
parent c043ba77
...@@ -139,6 +139,7 @@ static void *createArrayObject(const redisReadTask *task, int elements) { ...@@ -139,6 +139,7 @@ static void *createArrayObject(const redisReadTask *task, int elements) {
return NULL; return NULL;
if (elements > 0) { if (elements > 0) {
if (SIZE_MAX / sizeof(redisReply*) < elements) return NULL; /* Don't overflow */
r->element = calloc(elements,sizeof(redisReply*)); r->element = calloc(elements,sizeof(redisReply*));
if (r->element == NULL) { if (r->element == NULL) {
freeReplyObject(r); freeReplyObject(r);
......
...@@ -302,6 +302,20 @@ static void test_reply_reader(void) { ...@@ -302,6 +302,20 @@ static void test_reply_reader(void) {
strncasecmp(reader->errstr,"No support for",14) == 0); strncasecmp(reader->errstr,"No support for",14) == 0);
redisReaderFree(reader); redisReaderFree(reader);
test("Multi-bulk never overflows regardless of maxelements: ");
size_t bad_mbulk_len = (SIZE_MAX / sizeof(void *)) + 3;
char bad_mbulk_reply[100];
snprintf(bad_mbulk_reply, sizeof(bad_mbulk_reply), "*%llu\r\n+asdf\r\n",
(unsigned long long) bad_mbulk_len);
reader = redisReaderCreate();
reader->maxelements = 0; /* Don't rely on default limit */
redisReaderFeed(reader, bad_mbulk_reply, strlen(bad_mbulk_reply));
ret = redisReaderGetReply(reader,&reply);
test_cond(ret == REDIS_ERR && strcasecmp(reader->errstr, "Out of memory") == 0);
freeReplyObject(reply);
redisReaderFree(reader);
test("Works with NULL functions for reply: "); test("Works with NULL functions for reply: ");
reader = redisReaderCreate(); reader = redisReaderCreate();
reader->fn = NULL; reader->fn = NULL;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment