summaryrefslogtreecommitdiff
path: root/src/intset.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2020-08-14 16:05:34 +0300
committerOran Agra <oran@redislabs.com>2020-12-06 14:54:34 +0200
commitc31055db617a7fedb20c28c245ddad8ed2b11931 (patch)
tree26a99ffd2567164ec0316252d577964b25103659 /src/intset.c
parent01c13bddea6c09e0a60678fa48becd42b0913515 (diff)
downloadredis-c31055db617a7fedb20c28c245ddad8ed2b11931.tar.gz
Sanitize dump payload: fuzz tester and fixes for segfaults and leaks it exposed
The test creates keys with various encodings, DUMP them, corrupt the payload and RESTORES it. It utilizes the recently added use-exit-on-panic config to distinguish between asserts and segfaults. If the restore succeeds, it runs random commands on the key to attempt to trigger a crash. It runs in two modes, one with deep sanitation enabled and one without. In the first one we don't expect any assertions or segfaults, in the second one we expect assertions, but no segfaults. We also check for leaks and invalid reads using valgrind, and if we find them we print the commands that lead to that issue. Changes in the code (other than the test): - Replace a few NPD (null pointer deference) flows and division by zero with an assertion, so that it doesn't fail the test. (since we set the server to use `exit` rather than `abort` on assertion). - Fix quite a lot of flows in rdb.c that could have lead to memory leaks in RESTORE command (since it now responds with an error rather than panic) - Add a DEBUG flag for SET-SKIP-CHECKSUM-VALIDATION so that the test don't need to bother with faking a valid checksum - Remove a pile of code in serverLogObjectDebugInfo which is actually unsafe to run in the crash report (see comments in the code) - fix a missing boundary check in lzf_decompress test suite infra improvements: - be able to run valgrind checks before the process terminates - rotate log files when restarting servers
Diffstat (limited to 'src/intset.c')
-rw-r--r--src/intset.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/intset.c b/src/intset.c
index 0079199cf..964a41187 100644
--- a/src/intset.c
+++ b/src/intset.c
@@ -34,6 +34,7 @@
#include "intset.h"
#include "zmalloc.h"
#include "endianconv.h"
+#include "redisassert.h"
/* Note that these encodings are ordered, so:
* INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */
@@ -258,7 +259,9 @@ uint8_t intsetFind(intset *is, int64_t value) {
/* Return random member */
int64_t intsetRandom(intset *is) {
- return _intsetGet(is,rand()%intrev32ifbe(is->length));
+ uint32_t len = intrev32ifbe(is->length);
+ assert(len); /* avoid division by zero on corrupt intset payload. */
+ return _intsetGet(is,rand()%len);
}
/* Get the value at the given position. When this position is