Skip to content

Commit 0215324

Browse files
oranagrayossigo
andauthored
Fix redis-cli / redis-sential overflow on some platforms (CVE-2021-32762) (#9587)
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. Co-authored-by: Yossi Gottlieb <yossigo@gmail.com>
1 parent 7cb89a5 commit 0215324

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

Diff for: deps/hiredis/hiredis.c

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ static void *createArrayObject(const redisReadTask *task, size_t elements) {
174174
return NULL;
175175

176176
if (elements > 0) {
177+
if (SIZE_MAX / sizeof(redisReply*) < elements) return NULL; /* Don't overflow */
177178
r->element = hi_calloc(elements,sizeof(redisReply*));
178179
if (r->element == NULL) {
179180
freeReplyObject(r);

Diff for: deps/hiredis/test.c

+14
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,20 @@ static void test_reply_reader(void) {
498498
freeReplyObject(reply);
499499
redisReaderFree(reader);
500500

501+
test("Multi-bulk never overflows regardless of maxelements: ");
502+
size_t bad_mbulk_len = (SIZE_MAX / sizeof(void *)) + 3;
503+
char bad_mbulk_reply[100];
504+
snprintf(bad_mbulk_reply, sizeof(bad_mbulk_reply), "*%llu\r\n+asdf\r\n",
505+
(unsigned long long) bad_mbulk_len);
506+
507+
reader = redisReaderCreate();
508+
reader->maxelements = 0; /* Don't rely on default limit */
509+
redisReaderFeed(reader, bad_mbulk_reply, strlen(bad_mbulk_reply));
510+
ret = redisReaderGetReply(reader,&reply);
511+
test_cond(ret == REDIS_ERR && strcasecmp(reader->errstr, "Out of memory") == 0);
512+
freeReplyObject(reply);
513+
redisReaderFree(reader);
514+
501515
#if LLONG_MAX > SIZE_MAX
502516
test("Set error when array > SIZE_MAX: ");
503517
reader = redisReaderCreate();

0 commit comments

Comments
 (0)