mirror of
http://github.com/valkey-io/valkey
synced 2024-11-22 00:52:38 +00:00
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
This commit is contained in:
parent
e0cf85b848
commit
a30d367a71
@ -34,6 +34,7 @@
|
|||||||
#include "intset.h"
|
#include "intset.h"
|
||||||
#include "zmalloc.h"
|
#include "zmalloc.h"
|
||||||
#include "endianconv.h"
|
#include "endianconv.h"
|
||||||
|
#include "redisassert.h"
|
||||||
|
|
||||||
/* Note that these encodings are ordered, so:
|
/* Note that these encodings are ordered, so:
|
||||||
* INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */
|
* INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */
|
||||||
@ -103,7 +104,8 @@ intset *intsetNew(void) {
|
|||||||
|
|
||||||
/* Resize the intset */
|
/* Resize the intset */
|
||||||
static intset *intsetResize(intset *is, uint32_t len) {
|
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);
|
is = zrealloc(is,sizeof(intset)+size);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
@ -1518,7 +1518,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key) {
|
|||||||
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
|
||||||
|
|
||||||
/* Use a regular set when there are too many entries. */
|
/* 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();
|
o = createSetObject();
|
||||||
/* It's faster to expand the dict to the right size asap in order
|
/* It's faster to expand the dict to the right size asap in order
|
||||||
* to avoid rehashing */
|
* to avoid rehashing */
|
||||||
|
@ -66,7 +66,10 @@ int setTypeAdd(robj *subject, sds value) {
|
|||||||
if (success) {
|
if (success) {
|
||||||
/* Convert to regular set when the intset contains
|
/* Convert to regular set when the intset contains
|
||||||
* too many entries. */
|
* 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);
|
setTypeConvert(subject,OBJ_ENCODING_HT);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user