diff options
author | Oran Agra <oran@redislabs.com> | 2021-10-04 12:09:25 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-04 12:09:25 +0300 |
commit | 7cb89a5a1cc8ee0b003a36b2eba42573c09c45f9 (patch) | |
tree | f230718f561386a8e5698aae3e298cf942265dfe | |
parent | 24cc0b984d4ed5045c6ff125b0e619b6ce5ea9c6 (diff) | |
download | redis-7cb89a5a1cc8ee0b003a36b2eba42573c09c45f9.tar.gz |
Fix Integer overflow issue with intsets (CVE-2021-32687) (#9586)
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
-rw-r--r-- | src/intset.c | 3 | ||||
-rw-r--r-- | src/rdb.c | 4 | ||||
-rw-r--r-- | src/t_set.c | 5 |
3 files changed, 9 insertions, 3 deletions
diff --git a/src/intset.c b/src/intset.c index 4a9214864..0e8365b46 100644 --- a/src/intset.c +++ b/src/intset.c @@ -104,7 +104,8 @@ intset *intsetNew(void) { /* Resize the intset */ static intset *intsetResize(intset *is, uint32_t len) { - uint32_t size = len*intrev32ifbe(is->encoding); + uint64_t size = (uint64_t)len*intrev32ifbe(is->encoding); + assert(size <= SIZE_MAX - sizeof(intset)); is = zrealloc(is,sizeof(intset)+size); return is; } @@ -1690,7 +1690,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (len == 0) goto emptykey; /* Use a regular set when there are too many entries. */ - if (len > server.set_max_intset_entries) { + size_t max_entries = server.set_max_intset_entries; + if (max_entries >= 1<<30) max_entries = 1<<30; + if (len > max_entries) { o = createSetObject(); /* It's faster to expand the dict to the right size asap in order * to avoid rehashing */ diff --git a/src/t_set.c b/src/t_set.c index 383d0c692..3823f1cbb 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -66,7 +66,10 @@ int setTypeAdd(robj *subject, sds value) { if (success) { /* Convert to regular set when the intset contains * too many entries. */ - if (intsetLen(subject->ptr) > server.set_max_intset_entries) + size_t max_entries = server.set_max_intset_entries; + /* limit to 1G entries due to intset internals. */ + if (max_entries >= 1<<30) max_entries = 1<<30; + if (intsetLen(subject->ptr) > max_entries) setTypeConvert(subject,OBJ_ENCODING_HT); return 1; } |