diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index c75d1d00..a3817af3 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -187,3 +187,44 @@ jobs: - name: cluster tests run: ./runtest-cluster + test-alpine-jemalloc: + runs-on: ubuntu-latest + if: github.repository == 'redis/redis' + container: alpine:latest + steps: + - uses: actions/checkout@v2 + - name: make + run: | + apk add build-base + make REDIS_CFLAGS='-Werror' + - name: test + run: | + apk add tcl procps + ./runtest --accurate --verbose + - name: module api test + run: ./runtest-moduleapi --verbose + - name: sentinel tests + run: ./runtest-sentinel + - name: cluster tests + run: ./runtest-cluster + + test-alpine-libc-malloc: + runs-on: ubuntu-latest + if: github.repository == 'redis/redis' + container: alpine:latest + steps: + - uses: actions/checkout@v2 + - name: make + run: | + apk add build-base + make REDIS_CFLAGS='-Werror' USE_JEMALLOC=no + - name: test + run: | + apk add tcl procps + ./runtest --accurate --verbose + - name: module api test + run: ./runtest-moduleapi --verbose + - name: sentinel tests + run: ./runtest-sentinel + - name: cluster tests + run: ./runtest-cluster diff --git a/00-RELEASENOTES b/00-RELEASENOTES index 1b18cbf4..3d8c17a7 100644 --- a/00-RELEASENOTES +++ b/00-RELEASENOTES @@ -11,6 +11,63 @@ CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. SECURITY: There are security fixes in the release. -------------------------------------------------------------------------------- +================================================================================ +Redis 6.0.14 Released Tue July 1 12:00:00 IST 2021 +================================================================================ + +Upgrade urgency: SECURITY, Contains fixes to security issues that affect +authenticated client connections. MODERATE otherwise. + +Fix integer overflow in STRALGO LCS (CVE-2021-32625) +An integer overflow bug in Redis version 6.0 or newer can be exploited using the +STRALGO LCS command to corrupt the heap and potentially result with remote code +execution. This is a result of an incomplete fix by CVE-2021-29477. + +Other bug fixes: +* Fix crash in UNLINK on a stream key with deleted consumer groups (#8932) +* SINTERSTORE: Add missing keyspace del event when none of the sources exist (#8949) + +================================================================================ +Redis 6.0.13 Released Mon May 3 19:00:00 IST 2021 +================================================================================ + +Upgrade urgency: SECURITY, Contains fixes to security issues that affect +authenticated client connections. LOW otherwise. + +Integer overflow in STRALGO LCS command (CVE-2021-29477): +An integer overflow bug in Redis version 6.0 or newer could be exploited using +the STRALGO LCS command to corrupt the heap and potentially result in remote +code execution. The integer overflow bug exists in all versions of Redis +starting with 6.0. + +Integer overflow in COPY command for large intsets (CVE-2021-29478): +An integer overflow bug in Redis 6.2 could be exploited to corrupt the heap and +potentially result with remote code execution. The vulnerability involves +changing the default set-max-intset-entries configuration value, creating a +large set key that consists of integer values and using the COPY command to +duplicate it. The integer overflow bug exists in all versions of Redis starting +with 2.6, where it could result with a corrupted RDB or DUMP payload, but not +exploited through COPY (which did not exist before 6.2). + +Bug fixes: +* Cluster: Skip unnecessary check which may prevent failure detection (#8585) +* Fix not starting on alpine/libmusl without IPv6 (#8655) + +Improvements: +* Fix performance regression in BRPOP on Redis 6.0 (#8689) + +Modules: +* Fix edge-case when a module client is unblocked (#8618) + +================================================================================ +Redis 6.0.12 Released Mon Mar 1 17:29:52 IST 2021 +================================================================================ + +Upgrade urgency: LOW, fixes a compilation issue. + +Bug fixes: +* Fix compilation error on non-glibc systems if jemalloc is not used (#8533) + ================================================================================ Redis 6.0.11 Released Mon Feb 22 16:13:23 IST 2021 ================================================================================ diff --git a/debian/changelog b/debian/changelog index 18149d7e..0a0ab0a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,26 @@ +redis (5:6.0.14-1) unstable; urgency=medium + + * CVE-2021-32625: Fix a vulnerability in the STRALGO LCS command. + (Closes: #989351) + + -- Chris Lamb Tue, 01 Jun 2021 17:35:19 +0100 + +redis (5:6.0.13-1) unstable; urgency=medium + + * New upstream security release: + - CVE-2021-29477: Vulnerability in the STRALGO LCS command. + - CVE-2021-29478: Vulnerability in the COPY command for large intsets. + (Closes: #988045) + * Refresh patches. + + -- Chris Lamb Tue, 04 May 2021 11:06:14 +0100 + +redis (5:6.0.12-1) unstable; urgency=medium + + * New upstream release. + + -- Chris Lamb Sat, 06 Mar 2021 11:03:47 +0000 + redis (5:6.0.11-1) unstable; urgency=medium * New upstream release, incorporating security issues. (Closes: #983446) diff --git a/debian/patches/0001-fix-ftbfs-on-kfreebsd.patch b/debian/patches/0001-fix-ftbfs-on-kfreebsd.patch index 65c15521..a9dcd86e 100644 --- a/debian/patches/0001-fix-ftbfs-on-kfreebsd.patch +++ b/debian/patches/0001-fix-ftbfs-on-kfreebsd.patch @@ -7,7 +7,7 @@ Subject: fix-ftbfs-on-kfreebsd 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmacros.h b/src/fmacros.h -index 6e56c75..d490aec 100644 +index a97d21a..4b2d895 100644 --- a/src/fmacros.h +++ b/src/fmacros.h @@ -41,7 +41,7 @@ diff --git a/debian/patches/0009-Send-the-readiness-notification-when-we-are-ready-to.patch b/debian/patches/0009-Send-the-readiness-notification-when-we-are-ready-to.patch index 4866f732..c7a401a7 100644 --- a/debian/patches/0009-Send-the-readiness-notification-when-we-are-ready-to.patch +++ b/debian/patches/0009-Send-the-readiness-notification-when-we-are-ready-to.patch @@ -53,10 +53,10 @@ index 5ce9f02..c408219 100644 return; } diff --git a/src/server.c b/src/server.c -index 2cabb2e..5f27b09 100644 +index c3131b5..599453d 100644 --- a/src/server.c +++ b/src/server.c -@@ -5516,10 +5516,10 @@ int main(int argc, char **argv) { +@@ -5517,10 +5517,10 @@ int main(int argc, char **argv) { if (server.supervised_mode == SUPERVISED_SYSTEMD) { if (!server.masterhost) { redisCommunicateSystemd("STATUS=Ready to accept connections\n"); diff --git a/debian/patches/0010-Add-support-for-USE_SYSTEM_JEMALLOC-flag.patch b/debian/patches/0010-Add-support-for-USE_SYSTEM_JEMALLOC-flag.patch index 7a77c19c..3a2d5df2 100644 --- a/debian/patches/0010-Add-support-for-USE_SYSTEM_JEMALLOC-flag.patch +++ b/debian/patches/0010-Add-support-for-USE_SYSTEM_JEMALLOC-flag.patch @@ -47,7 +47,7 @@ index e1cd2c2..85b1ad8 100644 ifeq ($(BUILD_TLS),yes) FINAL_CFLAGS+=-DUSE_OPENSSL $(OPENSSL_CFLAGS) diff --git a/src/debug.c b/src/debug.c -index a85ffe2..2883a14 100644 +index 5747175..e32a83f 100644 --- a/src/debug.c +++ b/src/debug.c @@ -53,6 +53,10 @@ typedef ucontext_t sigcontext_t; @@ -62,7 +62,7 @@ index a85ffe2..2883a14 100644 /* Compute the sha1 of string at 's' with 'len' bytes long. diff --git a/src/object.c b/src/object.c -index 17a193b..0741e5f 100644 +index 45cd92b..cacc564 100644 --- a/src/object.c +++ b/src/object.c @@ -36,6 +36,11 @@ @@ -78,10 +78,10 @@ index 17a193b..0741e5f 100644 robj *createObject(int type, void *ptr) { diff --git a/src/zmalloc.c b/src/zmalloc.c -index 0dd7918..dd0d79b 100644 +index beae8d6..9106520 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c -@@ -69,6 +69,15 @@ void zlibc_free(void *ptr) { +@@ -66,6 +66,15 @@ void zlibc_free(void *ptr) { #define realloc(ptr,size) tc_realloc(ptr,size) #define free(ptr) tc_free(ptr) #elif defined(USE_JEMALLOC) @@ -97,7 +97,7 @@ index 0dd7918..dd0d79b 100644 #define malloc(size) je_malloc(size) #define calloc(count,size) je_calloc(count,size) #define realloc(ptr,size) je_realloc(ptr,size) -@@ -76,6 +85,7 @@ void zlibc_free(void *ptr) { +@@ -73,6 +82,7 @@ void zlibc_free(void *ptr) { #define mallocx(size,flags) je_mallocx(size,flags) #define dallocx(ptr,flags) je_dallocx(ptr,flags) #endif diff --git a/debian/watch b/debian/watch index 9922010d..cd1111e9 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=4 opts=uversionmangle=s/-?(alpha|beta|rc)/~$1/ \ - https://github.com/antirez/redis/releases .*/archive/(6\.[01]\..*).tar.gz + https://github.com/redis/redis/releases .*/(6\.0\.[^/]+).tar.gz diff --git a/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h b/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h index 2685802b..b19a9420 100644 --- a/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h +++ b/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h @@ -235,7 +235,7 @@ iget_defrag_hint(tsdn_t *tsdn, void* ptr) { int free_in_slab = extent_nfree_get(slab); if (free_in_slab) { const bin_info_t *bin_info = &bin_infos[binind]; - int curslabs = bin->stats.curslabs; + unsigned long curslabs = bin->stats.curslabs; size_t curregs = bin->stats.curregs; if (bin->slabcur) { /* remove slabcur from the overall utilization */ diff --git a/src/blocked.c b/src/blocked.c index 396a7156..460362ce 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -425,6 +425,10 @@ void serveClientsBlockedOnStreamKey(robj *o, readyList *rl) { void serveClientsBlockedOnKeyByModule(readyList *rl) { dictEntry *de; + /* Optimization: If no clients are in type BLOCKED_MODULE, + * we can skip this loop. */ + if (!server.blocked_clients_by_type[BLOCKED_MODULE]) return; + /* We serve clients in the same order they blocked for * this key, from the first blocked to the last. */ de = dictFind(rl->db->blocking_keys,rl->key); diff --git a/src/cluster.c b/src/cluster.c index 2d4d417e..7b46c343 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -3627,7 +3627,6 @@ void clusterCron(void) { now - node->link->ctime > server.cluster_node_timeout && /* was not already reconnected */ node->ping_sent && /* we already sent a ping */ - node->pong_received < node->ping_sent && /* still waiting pong */ /* and we are waiting for the pong more than timeout/2 */ ping_delay > server.cluster_node_timeout/2 && /* and in such interval we are not seeing any traffic at all. */ diff --git a/src/config.h b/src/config.h index b9c68f38..67f46de4 100644 --- a/src/config.h +++ b/src/config.h @@ -35,7 +35,6 @@ #endif #ifdef __linux__ -#include #include #endif @@ -99,19 +98,7 @@ /* Define rdb_fsync_range to sync_file_range() on Linux, otherwise we use * the plain fsync() call. */ -#ifdef __linux__ -#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) -#if (LINUX_VERSION_CODE >= 0x020611 && __GLIBC_PREREQ(2, 6)) -#define HAVE_SYNC_FILE_RANGE 1 -#endif -#else -#if (LINUX_VERSION_CODE >= 0x020611) -#define HAVE_SYNC_FILE_RANGE 1 -#endif -#endif -#endif - -#ifdef HAVE_SYNC_FILE_RANGE +#if (defined(__linux__) && defined(SYNC_FILE_RANGE_WAIT_BEFORE)) #define rdb_fsync_range(fd,off,size) sync_file_range(fd,off,size,SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE) #else #define rdb_fsync_range(fd,off,size) fsync(fd) @@ -128,7 +115,7 @@ #define ESOCKTNOSUPPORT 0 #endif -#if ((defined __linux && defined(__GLIBC__)) || defined __APPLE__) +#if (defined __linux || defined __APPLE__) #define USE_SETPROCTITLE #define INIT_SETPROCTITLE_REPLACEMENT void spt_init(int argc, char *argv[]); diff --git a/src/debug.c b/src/debug.c index a85ffe21..5747175b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1640,8 +1640,8 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { serverLog(LL_WARNING, "Accessing address: %p", (void*)info->si_addr); } - if (info->si_pid != -1) { - serverLog(LL_WARNING, "Killed by PID: %d, UID: %d", info->si_pid, info->si_uid); + if (info->si_code <= SI_USER && info->si_pid != -1) { + serverLog(LL_WARNING, "Killed by PID: %ld, UID: %d", (long) info->si_pid, info->si_uid); } serverLog(LL_WARNING, "Failed assertion: %s (%s:%d)", server.assert_failed, diff --git a/src/fmacros.h b/src/fmacros.h index 6e56c759..a97d21a4 100644 --- a/src/fmacros.h +++ b/src/fmacros.h @@ -58,4 +58,9 @@ #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 +#ifdef __linux__ +/* features.h uses the defines above to set feature specific defines. */ +#include +#endif + #endif diff --git a/src/intset.c b/src/intset.c index 4445a5ca..19f6562e 100644 --- a/src/intset.c +++ b/src/intset.c @@ -278,7 +278,7 @@ uint32_t intsetLen(const intset *is) { /* Return intset blob size in bytes. */ size_t intsetBlobLen(intset *is) { - return sizeof(intset)+intrev32ifbe(is->length)*intrev32ifbe(is->encoding); + return sizeof(intset)+(size_t)intrev32ifbe(is->length)*intrev32ifbe(is->encoding); } #ifdef REDIS_TEST diff --git a/src/lazyfree.c b/src/lazyfree.c index 31197df2..2557a750 100644 --- a/src/lazyfree.c +++ b/src/lazyfree.c @@ -52,7 +52,7 @@ size_t lazyfreeGetFreeEffort(robj *obj) { /* Every consumer group is an allocation and so are the entries in its * PEL. We use size of the first group's PEL as an estimate for all * others. */ - if (s->cgroups) { + if (s->cgroups && raxSize(s->cgroups)) { raxIterator ri; streamCG *cg; raxStart(&ri,s->cgroups); diff --git a/src/lolwut.c b/src/lolwut.c index eebd5da6..931f311c 100644 --- a/src/lolwut.c +++ b/src/lolwut.c @@ -94,8 +94,8 @@ lwCanvas *lwCreateCanvas(int width, int height, int bgcolor) { lwCanvas *canvas = zmalloc(sizeof(*canvas)); canvas->width = width; canvas->height = height; - canvas->pixels = zmalloc(width*height); - memset(canvas->pixels,bgcolor,width*height); + canvas->pixels = zmalloc((size_t)width*height); + memset(canvas->pixels,bgcolor,(size_t)width*height); return canvas; } diff --git a/src/memtest.c b/src/memtest.c index cb4d35e8..bc0ac3a6 100644 --- a/src/memtest.c +++ b/src/memtest.c @@ -71,7 +71,7 @@ void memtest_progress_start(char *title, int pass) { printf("\x1b[H\x1b[2K"); /* Cursor home, clear current line. */ printf("%s [%d]\n", title, pass); /* Print title. */ progress_printed = 0; - progress_full = ws.ws_col*(ws.ws_row-3); + progress_full = (size_t)ws.ws_col*(ws.ws_row-3); fflush(stdout); } diff --git a/src/module.c b/src/module.c index b5828298..9278bbcb 100644 --- a/src/module.c +++ b/src/module.c @@ -4830,6 +4830,12 @@ void moduleHandleBlockedClients(void) { * API to unblock the client and the memory will be released. */ void moduleBlockedClientTimedOut(client *c) { RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle; + + /* Protect against re-processing: don't serve clients that are already + * in the unblocking list for any reason (including RM_UnblockClient() + * explicit call). See #6798. */ + if (bc->unblocked) return; + RedisModuleCtx ctx = REDISMODULE_CTX_INIT; ctx.flags |= REDISMODULE_CTX_BLOCKED_TIMEOUT; ctx.module = bc->module; diff --git a/src/object.c b/src/object.c index 17a193b6..45cd92b5 100644 --- a/src/object.c +++ b/src/object.c @@ -821,7 +821,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { if (samples) asize += (double)elesize/samples*dictSize(d); } else if (o->encoding == OBJ_ENCODING_INTSET) { intset *is = o->ptr; - asize = sizeof(*o)+sizeof(*is)+is->encoding*is->length; + asize = sizeof(*o)+sizeof(*is)+(size_t)is->encoding*is->length; } else { serverPanic("Unknown set encoding"); } diff --git a/src/redis-check-rdb.c b/src/redis-check-rdb.c index 6d60cf3e..7a6a2caa 100644 --- a/src/redis-check-rdb.c +++ b/src/redis-check-rdb.c @@ -249,7 +249,7 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) { rdbstate.doing = RDB_CHECK_DOING_READ_LEN; if ((dbid = rdbLoadLen(&rdb,NULL)) == RDB_LENERR) goto eoferr; - rdbCheckInfo("Selecting DB ID %d", dbid); + rdbCheckInfo("Selecting DB ID %llu", (unsigned long long)dbid); continue; /* Read type again. */ } else if (type == RDB_OPCODE_RESIZEDB) { /* RESIZEDB: Hint about the size of the keys in the currently diff --git a/src/redis-cli.c b/src/redis-cli.c index 2d27c38d..8e2bfef8 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -1360,6 +1360,7 @@ static int cliSendCommand(int argc, char **argv, long repeat) { printf("Reading messages... (press Ctrl-C to quit)\n"); while (1) { if (cliReadReply(output_raw) != REDIS_OK) exit(1); + fflush(stdout); /* Make it grep friendly */ } } @@ -5325,7 +5326,7 @@ static void clusterManagerNodeArrayReset(clusterManagerNodeArray *array) { static void clusterManagerNodeArrayShift(clusterManagerNodeArray *array, clusterManagerNode **nodeptr) { - assert(array->nodes < (array->nodes + array->len)); + assert(array->len > 0); /* If the first node to be shifted is not NULL, decrement count. */ if (*array->nodes != NULL) array->count--; /* Store the first node to be shifted into 'nodeptr'. */ @@ -5338,7 +5339,7 @@ static void clusterManagerNodeArrayShift(clusterManagerNodeArray *array, static void clusterManagerNodeArrayAdd(clusterManagerNodeArray *array, clusterManagerNode *node) { - assert(array->nodes < (array->nodes + array->len)); + assert(array->len > 0); assert(node != NULL); assert(array->count < array->len); array->nodes[array->count++] = node; @@ -6684,7 +6685,7 @@ void showLatencyDistSamples(struct distsamples *samples, long long tot) { printf("\033[38;5;0m"); /* Set foreground color to black. */ for (j = 0; ; j++) { int coloridx = - ceil((float) samples[j].count / tot * (spectrum_palette_size-1)); + ceil((double) samples[j].count / tot * (spectrum_palette_size-1)); int color = spectrum_palette[coloridx]; printf("\033[48;5;%dm%c", (int)color, samples[j].character); samples[j].count = 0; diff --git a/src/sentinel.c b/src/sentinel.c index 969771d2..beaa18dd 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -3592,16 +3592,16 @@ void sentinelSetCommand(client *c) { int numargs = j-old_j+1; switch(numargs) { case 2: - sentinelEvent(LL_WARNING,"+set",ri,"%@ %s %s",c->argv[old_j]->ptr, - c->argv[old_j+1]->ptr); + sentinelEvent(LL_WARNING,"+set",ri,"%@ %s %s",(char*)c->argv[old_j]->ptr, + (char*)c->argv[old_j+1]->ptr); break; case 3: - sentinelEvent(LL_WARNING,"+set",ri,"%@ %s %s %s",c->argv[old_j]->ptr, - c->argv[old_j+1]->ptr, - c->argv[old_j+2]->ptr); + sentinelEvent(LL_WARNING,"+set",ri,"%@ %s %s %s",(char*)c->argv[old_j]->ptr, + (char*)c->argv[old_j+1]->ptr, + (char*)c->argv[old_j+2]->ptr); break; default: - sentinelEvent(LL_WARNING,"+set",ri,"%@ %s",c->argv[old_j]->ptr); + sentinelEvent(LL_WARNING,"+set",ri,"%@ %s",(char*)c->argv[old_j]->ptr); break; } } diff --git a/src/server.c b/src/server.c index 2cabb2e0..c3131b5d 100644 --- a/src/server.c +++ b/src/server.c @@ -2765,13 +2765,14 @@ int listenToPort(int port, int *fds, int *count) { server.tcp_backlog); } if (fds[*count] == ANET_ERR) { + int net_errno = errno; serverLog(LL_WARNING, "Could not create server TCP listening socket %s:%d: %s", server.bindaddr[j] ? server.bindaddr[j] : "*", port, server.neterr); - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || - errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || - errno == EAFNOSUPPORT || errno == EADDRNOTAVAIL) + if (net_errno == ENOPROTOOPT || net_errno == EPROTONOSUPPORT || + net_errno == ESOCKTNOSUPPORT || net_errno == EPFNOSUPPORT || + net_errno == EAFNOSUPPORT || net_errno == EADDRNOTAVAIL) continue; return C_ERR; } diff --git a/src/setproctitle.c b/src/setproctitle.c index 1c91570e..01940234 100644 --- a/src/setproctitle.c +++ b/src/setproctitle.c @@ -232,7 +232,7 @@ void spt_init(int argc, char *argv[]) { if (!(SPT.arg0 = strdup(argv[0]))) goto syerr; -#if __GLIBC__ +#if __linux__ if (!(tmp = strdup(program_invocation_name))) goto syerr; diff --git a/src/t_set.c b/src/t_set.c index 837337ba..5ea4e61e 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -809,6 +809,7 @@ void sinterGenericCommand(client *c, robj **setkeys, if (dstkey) { if (dbDelete(c->db,dstkey)) { signalModifiedKey(c,c->db,dstkey); + notifyKeyspaceEvent(NOTIFY_GENERIC,"del",dstkey,c->db->id); server.dirty++; } addReply(c,shared.czero); diff --git a/src/t_string.c b/src/t_string.c index 4886f7e4..34a452f4 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -568,6 +568,12 @@ void stralgoLCS(client *c) { goto cleanup; } + /* Detect string truncation or later overflows. */ + if (sdslen(a) >= UINT32_MAX-1 || sdslen(b) >= UINT32_MAX-1) { + addReplyError(c, "String too long for LCS"); + goto cleanup; + } + /* Compute the LCS using the vanilla dynamic programming technique of * building a table of LCS(x,y) substrings. */ uint32_t alen = sdslen(a); @@ -576,9 +582,19 @@ void stralgoLCS(client *c) { /* Setup an uint32_t array to store at LCS[i,j] the length of the * LCS A0..i-1, B0..j-1. Note that we have a linear array here, so * we index it as LCS[j+(blen+1)*j] */ - uint32_t *lcs = zmalloc((alen+1)*(blen+1)*sizeof(uint32_t)); #define LCS(A,B) lcs[(B)+((A)*(blen+1))] + /* Try to allocate the LCS table, and abort on overflow or insufficient memory. */ + unsigned long long lcssize = (unsigned long long)(alen+1)*(blen+1); /* Can't overflow due to the size limits above. */ + unsigned long long lcsalloc = lcssize * sizeof(uint32_t); + uint32_t *lcs = NULL; + if (lcsalloc < SIZE_MAX && lcsalloc / lcssize == sizeof(uint32_t)) + lcs = zmalloc(lcsalloc); + if (!lcs) { + addReplyError(c, "Insufficient memory"); + goto cleanup; + } + /* Start building the LCS table. */ for (uint32_t i = 0; i <= alen; i++) { for (uint32_t j = 0; j <= blen; j++) { diff --git a/src/version.h b/src/version.h index c8dbb320..b7b853cf 100644 --- a/src/version.h +++ b/src/version.h @@ -1,2 +1,2 @@ -#define REDIS_VERSION "6.0.11" -#define REDIS_VERSION_NUM 0x0006000b +#define REDIS_VERSION "6.0.14" +#define REDIS_VERSION_NUM 0x0006000e diff --git a/src/zmalloc.c b/src/zmalloc.c index 0dd7918b..beae8d65 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -31,6 +31,7 @@ #include #include #include +#include /* This function provide us access to the original libc free(). This is useful * for instance to free results obtained by backtrace_symbols(). We need @@ -48,18 +49,14 @@ void zlibc_free(void *ptr) { #ifdef HAVE_MALLOC_SIZE #define PREFIX_SIZE (0) +#define ASSERT_NO_SIZE_OVERFLOW(sz) #else #if defined(__sun) || defined(__sparc) || defined(__sparc__) #define PREFIX_SIZE (sizeof(long long)) #else #define PREFIX_SIZE (sizeof(size_t)) #endif -#endif - -#if PREFIX_SIZE > 0 #define ASSERT_NO_SIZE_OVERFLOW(sz) assert((sz) + PREFIX_SIZE > (sz)) -#else -#define ASSERT_NO_SIZE_OVERFLOW(sz) #endif /* Explicitly override malloc/free etc when using tcmalloc. */ diff --git a/tests/integration/logging.tcl b/tests/integration/logging.tcl index c1f4854d..a52ed86c 100644 --- a/tests/integration/logging.tcl +++ b/tests/integration/logging.tcl @@ -1,7 +1,20 @@ set server_path [tmpdir server.log] set system_name [string tolower [exec uname -s]] +set system_supported 0 -if {$system_name eq {linux} || $system_name eq {darwin}} { +# We only support darwin or Linux with glibc +if {$system_name eq {darwin}} { + set system_supported 1 +} elseif {$system_name eq {linux}} { + # Avoid the test on libmusl, which does not support backtrace + set ldd [exec ldd src/redis-server] + if {![string match {*libc.musl*} $ldd]} { + set system_supported 1 + } +} + +if {$system_supported} { + set server_path [tmpdir server.log] start_server [list overrides [list dir $server_path]] { test "Server is able to generate a stack trace on selected systems" { r config set watchdog-period 200 diff --git a/tests/unit/oom-score-adj.tcl b/tests/unit/oom-score-adj.tcl index cf671fe6..892b1a7a 100644 --- a/tests/unit/oom-score-adj.tcl +++ b/tests/unit/oom-score-adj.tcl @@ -39,7 +39,12 @@ if {$system_name eq {linux}} { r bgsave set child_pid [get_child_pid 0] - assert {[get_oom_score_adj $child_pid] == [expr $base + 30]} + # Wait until background child process to setOOMScoreAdj success. + wait_for_condition 100 10 { + [get_oom_score_adj $child_pid] == [expr $base + 30] + } else { + fail "Set oom-score-adj of background child process is not ok" + } } # Failed oom-score-adj tests can only run unprivileged