Skip to content

Commit a30d367

Browse files
committed
Fix Integer overflow issue with intsets (CVE-2021-32687)
The vulnerability involves changing the default set-max-intset-entries configuration parameter to a very large value and constructing specially crafted commands to manipulate sets
1 parent e0cf85b commit a30d367

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

Diff for: src/intset.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "intset.h"
3535
#include "zmalloc.h"
3636
#include "endianconv.h"
37+
#include "redisassert.h"
3738

3839
/* Note that these encodings are ordered, so:
3940
* INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */
@@ -103,7 +104,8 @@ intset *intsetNew(void) {
103104

104105
/* Resize the intset */
105106
static intset *intsetResize(intset *is, uint32_t len) {
106-
uint32_t size = len*intrev32ifbe(is->encoding);
107+
uint64_t size = (uint64_t)len*intrev32ifbe(is->encoding);
108+
assert(size <= SIZE_MAX - sizeof(intset));
107109
is = zrealloc(is,sizeof(intset)+size);
108110
return is;
109111
}

Diff for: src/rdb.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key) {
15181518
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
15191519

15201520
/* Use a regular set when there are too many entries. */
1521-
if (len > server.set_max_intset_entries) {
1521+
size_t max_entries = server.set_max_intset_entries;
1522+
if (max_entries >= 1<<30) max_entries = 1<<30;
1523+
if (len > max_entries) {
15221524
o = createSetObject();
15231525
/* It's faster to expand the dict to the right size asap in order
15241526
* to avoid rehashing */

Diff for: src/t_set.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ int setTypeAdd(robj *subject, sds value) {
6666
if (success) {
6767
/* Convert to regular set when the intset contains
6868
* too many entries. */
69-
if (intsetLen(subject->ptr) > server.set_max_intset_entries)
69+
size_t max_entries = server.set_max_intset_entries;
70+
/* limit to 1G entries due to intset internals. */
71+
if (max_entries >= 1<<30) max_entries = 1<<30;
72+
if (intsetLen(subject->ptr) > max_entries)
7073
setTypeConvert(subject,OBJ_ENCODING_HT);
7174
return 1;
7275
}

0 commit comments

Comments
 (0)