diff options
author | CoprDistGit <infra@openeuler.org> | 2024-11-01 08:40:22 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-11-01 08:40:22 +0000 |
commit | f1b1ad7c484d92241c4ae57bc579e33651022412 (patch) | |
tree | 50fa81f824beb8087d3852a4382dec52866e6e03 | |
parent | 4d42541db12e6bb7c4199fde46be11cda6345d60 (diff) |
automatic import of redisopeneuler24.03_LTS
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CVE-2019-10192-1.patch | 33 | ||||
-rw-r--r-- | CVE-2019-10192-2.patch | 35 | ||||
-rw-r--r-- | CVE-2022-24834.patch | 689 | ||||
-rw-r--r-- | CVE-2022-36021.patch | 92 | ||||
-rw-r--r-- | CVE-2023-28856.patch | 49 | ||||
-rw-r--r-- | CVE-2023-45145.patch | 66 | ||||
-rw-r--r-- | CVE-2024-31228.patch | 63 | ||||
-rw-r--r-- | CVE-2024-31449.patch | 43 | ||||
-rw-r--r-- | redis.spec | 69 | ||||
-rw-r--r-- | sources | 2 |
11 files changed, 1054 insertions, 88 deletions
@@ -1 +1,2 @@ /redis-4.0.11.tar.gz +/redis-5.0.4.tar.gz diff --git a/CVE-2019-10192-1.patch b/CVE-2019-10192-1.patch deleted file mode 100644 index f070446..0000000 --- a/CVE-2019-10192-1.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9f13b2bd4967334b1701c6eccdf53760cb13f79e Mon Sep 17 00:00:00 2001 -From: John Sully <john@csquare.ca> -Date: Thu, 14 Mar 2019 14:02:16 -0400 -Subject: [PATCH] Fix hyperloglog corruption - ---- - src/hyperloglog.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/hyperloglog.c b/src/hyperloglog.c -index fc21ea0065d..e993bf26e1d 100644 ---- a/src/hyperloglog.c -+++ b/src/hyperloglog.c -@@ -614,6 +614,10 @@ int hllSparseToDense(robj *o) { - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -+ if ((runlen + idx) > HLL_REGISTERS) { -+ sdsfree(dense); -+ return C_ERR; -+ } - while(runlen--) { - HLL_DENSE_SET_REGISTER(hdr->registers,idx,regval); - idx++; -@@ -1088,6 +1092,8 @@ int hllMerge(uint8_t *max, robj *hll) { - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -+ if ((runlen + i) > HLL_REGISTERS) -+ return C_ERR; - while(runlen--) { - if (regval > max[i]) max[i] = regval; - i++; diff --git a/CVE-2019-10192-2.patch b/CVE-2019-10192-2.patch deleted file mode 100644 index e40dbe0..0000000 --- a/CVE-2019-10192-2.patch +++ /dev/null @@ -1,35 +0,0 @@ -From e216ceaf0e099536fe3658a29dcb725d812364e0 Mon Sep 17 00:00:00 2001 -From: antirez <antirez@gmail.com> -Date: Fri, 15 Mar 2019 17:16:06 +0100 -Subject: [PATCH] HyperLogLog: handle wrong offset in the base case. - ---- - src/hyperloglog.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/src/hyperloglog.c b/src/hyperloglog.c -index 526510b43b9..1e7ce3dceb7 100644 ---- a/src/hyperloglog.c -+++ b/src/hyperloglog.c -@@ -614,10 +614,7 @@ int hllSparseToDense(robj *o) { - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -- if ((runlen + idx) > HLL_REGISTERS) { -- sdsfree(dense); -- return C_ERR; -- } -+ if ((runlen + idx) > HLL_REGISTERS) break; /* Overflow. */ - while(runlen--) { - HLL_DENSE_SET_REGISTER(hdr->registers,idx,regval); - idx++; -@@ -1097,8 +1094,7 @@ int hllMerge(uint8_t *max, robj *hll) { - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -- if ((runlen + i) > HLL_REGISTERS) -- return C_ERR; -+ if ((runlen + i) > HLL_REGISTERS) break; /* Overflow. */ - while(runlen--) { - if (regval > max[i]) max[i] = regval; - i++; diff --git a/CVE-2022-24834.patch b/CVE-2022-24834.patch new file mode 100644 index 0000000..25ce44b --- /dev/null +++ b/CVE-2022-24834.patch @@ -0,0 +1,689 @@ +From 4fe8a0af3f479a4a5b17885334cb67a3887ae96e Mon Sep 17 00:00:00 2001 +From: Oran Agra <oran@redislabs.com> +Date: Sun, 2 Jul 2023 14:56:10 +0300 +Subject: [PATCH] Lua cjson and cmsgpack integer overflow issues + (CVE-2022-24834) + +* Fix integer overflows due to using wrong integer size. +* Add assertions / panic when overflow still happens. +* Deletion of dead code to avoid need to maintain it +* Some changes are not because of bugs, but rather paranoia. +* Improve cmsgpack and cjson test coverage. + +Co-authored-by: Yossi Gottlieb <yossigo@gmail.com> + +Origin: https://github.com/redis/redis/commit/4fe8a0af3f479a4a5b17885334cb67a3887ae96e + +--- + deps/Makefile | 7 ++ + deps/lua/src/lua_cjson.c | 9 ++- + deps/lua/src/lua_cmsgpack.c | 31 +++++---- + deps/lua/src/strbuf.c | 109 ++++++++------------------------ + deps/lua/src/strbuf.h | 46 ++++++-------- + tests/unit/scripting.tcl | 123 ++++++++++++++++++++++++++++++++++++ + 6 files changed, 200 insertions(+), 125 deletions(-) + +diff --git a/deps/Makefile b/deps/Makefile +index 700867f3b61c..dea4cd656c6f 100644 +--- a/deps/Makefile ++++ b/deps/Makefile +@@ -2,6 +2,8 @@ + + uname_S:= $(shell sh -c 'uname -s 2>/dev/null || echo not') + ++LUA_COVERAGE?=no ++ + CCCOLOR="\033[34m" + LINKCOLOR="\033[34;1m" + SRCCOLOR="\033[33m" +@@ -64,6 +66,11 @@ endif + + LUA_CFLAGS+= -O2 -Wall -DLUA_ANSI -DENABLE_CJSON_GLOBAL -DREDIS_STATIC='' $(CFLAGS) + LUA_LDFLAGS+= $(LDFLAGS) ++ifeq ($(LUA_COVERAGE),yes) ++ LUA_CFLAGS += -fprofile-arcs -ftest-coverage ++ LUA_LDFLAGS += -fprofile-arcs -ftest-coverage ++endif ++ + # lua's Makefile defines AR="ar rcu", which is unusual, and makes it more + # challenging to cross-compile lua (and redis). These defines make it easier + # to fit redis into cross-compilation environments, which typically set AR. +diff --git a/deps/lua/src/lua_cjson.c b/deps/lua/src/lua_cjson.c +index c26c0d7b8ea4..991f5d31ddb3 100644 +--- a/deps/lua/src/lua_cjson.c ++++ b/deps/lua/src/lua_cjson.c +@@ -39,6 +39,7 @@ + #include <assert.h> + #include <string.h> + #include <math.h> ++#include <stdint.h> + #include <limits.h> + #include "lua.h" + #include "lauxlib.h" +@@ -141,13 +142,13 @@ typedef struct { + + typedef struct { + json_token_type_t type; +- int index; ++ size_t index; + union { + const char *string; + double number; + int boolean; + } value; +- int string_len; ++ size_t string_len; + } json_token_t; + + static const char *char2escape[256] = { +@@ -473,6 +474,8 @@ static void json_append_string(lua_State *l, strbuf_t *json, int lindex) + * This buffer is reused constantly for small strings + * If there are any excess pages, they won't be hit anyway. + * This gains ~5% speedup. */ ++ if (len > SIZE_MAX / 6 - 3) ++ abort(); /* Overflow check */ + strbuf_ensure_empty_length(json, len * 6 + 2); + + strbuf_append_char_unsafe(json, '\"'); +@@ -706,7 +709,7 @@ static int json_encode(lua_State *l) + strbuf_t local_encode_buf; + strbuf_t *encode_buf; + char *json; +- int len; ++ size_t len; + + luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument"); + +diff --git a/deps/lua/src/lua_cmsgpack.c b/deps/lua/src/lua_cmsgpack.c +index 892154793991..49879455a4a9 100644 +--- a/deps/lua/src/lua_cmsgpack.c ++++ b/deps/lua/src/lua_cmsgpack.c +@@ -117,7 +117,9 @@ mp_buf *mp_buf_new(lua_State *L) { + + void mp_buf_append(lua_State *L, mp_buf *buf, const unsigned char *s, size_t len) { + if (buf->free < len) { +- size_t newsize = (buf->len+len)*2; ++ size_t newsize = buf->len+len; ++ if (newsize < buf->len || newsize >= SIZE_MAX/2) abort(); ++ newsize *= 2; + + buf->b = (unsigned char*)mp_realloc(L, buf->b, buf->len + buf->free, newsize); + buf->free = newsize - buf->len; +@@ -173,7 +175,7 @@ void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) { + + void mp_encode_bytes(lua_State *L, mp_buf *buf, const unsigned char *s, size_t len) { + unsigned char hdr[5]; +- int hdrlen; ++ size_t hdrlen; + + if (len < 32) { + hdr[0] = 0xa0 | (len&0xff); /* fix raw */ +@@ -220,7 +222,7 @@ void mp_encode_double(lua_State *L, mp_buf *buf, double d) { + + void mp_encode_int(lua_State *L, mp_buf *buf, int64_t n) { + unsigned char b[9]; +- int enclen; ++ size_t enclen; + + if (n >= 0) { + if (n <= 127) { +@@ -290,9 +292,9 @@ void mp_encode_int(lua_State *L, mp_buf *buf, int64_t n) { + mp_buf_append(L,buf,b,enclen); + } + +-void mp_encode_array(lua_State *L, mp_buf *buf, int64_t n) { ++void mp_encode_array(lua_State *L, mp_buf *buf, uint64_t n) { + unsigned char b[5]; +- int enclen; ++ size_t enclen; + + if (n <= 15) { + b[0] = 0x90 | (n & 0xf); /* fix array */ +@@ -313,7 +315,7 @@ void mp_encode_array(lua_State *L, mp_buf *buf, int64_t n) { + mp_buf_append(L,buf,b,enclen); + } + +-void mp_encode_map(lua_State *L, mp_buf *buf, int64_t n) { ++void mp_encode_map(lua_State *L, mp_buf *buf, uint64_t n) { + unsigned char b[5]; + int enclen; + +@@ -790,7 +792,7 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { + } + } + +-int mp_unpack_full(lua_State *L, int limit, int offset) { ++int mp_unpack_full(lua_State *L, lua_Integer limit, lua_Integer offset) { + size_t len; + const char *s; + mp_cur c; +@@ -802,10 +804,10 @@ int mp_unpack_full(lua_State *L, int limit, int offset) { + if (offset < 0 || limit < 0) /* requesting negative off or lim is invalid */ + return luaL_error(L, + "Invalid request to unpack with offset of %d and limit of %d.", +- offset, len); ++ (int) offset, (int) len); + else if (offset > len) + return luaL_error(L, +- "Start offset %d greater than input length %d.", offset, len); ++ "Start offset %d greater than input length %d.", (int) offset, (int) len); + + if (decode_all) limit = INT_MAX; + +@@ -827,12 +829,13 @@ int mp_unpack_full(lua_State *L, int limit, int offset) { + /* c->left is the remaining size of the input buffer. + * subtract the entire buffer size from the unprocessed size + * to get our next start offset */ +- int offset = len - c.left; ++ size_t new_offset = len - c.left; ++ if (new_offset > LONG_MAX) abort(); + + luaL_checkstack(L, 1, "in function mp_unpack_full"); + + /* Return offset -1 when we have have processed the entire buffer. */ +- lua_pushinteger(L, c.left == 0 ? -1 : offset); ++ lua_pushinteger(L, c.left == 0 ? -1 : (lua_Integer) new_offset); + /* Results are returned with the arg elements still + * in place. Lua takes care of only returning + * elements above the args for us. +@@ -851,15 +854,15 @@ int mp_unpack(lua_State *L) { + } + + int mp_unpack_one(lua_State *L) { +- int offset = luaL_optinteger(L, 2, 0); ++ lua_Integer offset = luaL_optinteger(L, 2, 0); + /* Variable pop because offset may not exist */ + lua_pop(L, lua_gettop(L)-1); + return mp_unpack_full(L, 1, offset); + } + + int mp_unpack_limit(lua_State *L) { +- int limit = luaL_checkinteger(L, 2); +- int offset = luaL_optinteger(L, 3, 0); ++ lua_Integer limit = luaL_checkinteger(L, 2); ++ lua_Integer offset = luaL_optinteger(L, 3, 0); + /* Variable pop because offset may not exist */ + lua_pop(L, lua_gettop(L)-1); + +diff --git a/deps/lua/src/strbuf.c b/deps/lua/src/strbuf.c +index f0f7f4b9a366..775e8baf1be9 100644 +--- a/deps/lua/src/strbuf.c ++++ b/deps/lua/src/strbuf.c +@@ -26,6 +26,7 @@ + #include <stdlib.h> + #include <stdarg.h> + #include <string.h> ++#include <stdint.h> + + #include "strbuf.h" + +@@ -38,22 +39,22 @@ static void die(const char *fmt, ...) + va_end(arg); + fprintf(stderr, "\n"); + +- exit(-1); ++ abort(); + } + +-void strbuf_init(strbuf_t *s, int len) ++void strbuf_init(strbuf_t *s, size_t len) + { +- int size; ++ size_t size; + +- if (len <= 0) ++ if (!len) + size = STRBUF_DEFAULT_SIZE; + else +- size = len + 1; /* \0 terminator */ +- ++ size = len + 1; ++ if (size < len) ++ die("Overflow, len: %zu", len); + s->buf = NULL; + s->size = size; + s->length = 0; +- s->increment = STRBUF_DEFAULT_INCREMENT; + s->dynamic = 0; + s->reallocs = 0; + s->debug = 0; +@@ -65,7 +66,7 @@ void strbuf_init(strbuf_t *s, int len) + strbuf_ensure_null(s); + } + +-strbuf_t *strbuf_new(int len) ++strbuf_t *strbuf_new(size_t len) + { + strbuf_t *s; + +@@ -81,20 +82,10 @@ strbuf_t *strbuf_new(int len) + return s; + } + +-void strbuf_set_increment(strbuf_t *s, int increment) +-{ +- /* Increment > 0: Linear buffer growth rate +- * Increment < -1: Exponential buffer growth rate */ +- if (increment == 0 || increment == -1) +- die("BUG: Invalid string increment"); +- +- s->increment = increment; +-} +- + static inline void debug_stats(strbuf_t *s) + { + if (s->debug) { +- fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n", ++ fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %zd, size: %zd\n", + (long)s, s->reallocs, s->length, s->size); + } + } +@@ -113,7 +104,7 @@ void strbuf_free(strbuf_t *s) + free(s); + } + +-char *strbuf_free_to_string(strbuf_t *s, int *len) ++char *strbuf_free_to_string(strbuf_t *s, size_t *len) + { + char *buf; + +@@ -131,57 +122,62 @@ char *strbuf_free_to_string(strbuf_t *s, int *len) + return buf; + } + +-static int calculate_new_size(strbuf_t *s, int len) ++static size_t calculate_new_size(strbuf_t *s, size_t len) + { +- int reqsize, newsize; ++ size_t reqsize, newsize; + + if (len <= 0) + die("BUG: Invalid strbuf length requested"); + + /* Ensure there is room for optional NULL termination */ + reqsize = len + 1; ++ if (reqsize < len) ++ die("Overflow, len: %zu", len); + + /* If the user has requested to shrink the buffer, do it exactly */ + if (s->size > reqsize) + return reqsize; + + newsize = s->size; +- if (s->increment < 0) { ++ if (reqsize >= SIZE_MAX / 2) { ++ newsize = reqsize; ++ } else { + /* Exponential sizing */ + while (newsize < reqsize) +- newsize *= -s->increment; +- } else { +- /* Linear sizing */ +- newsize = ((newsize + s->increment - 1) / s->increment) * s->increment; ++ newsize *= 2; + } + ++ if (newsize < reqsize) ++ die("BUG: strbuf length would overflow, len: %zu", len); ++ + return newsize; + } + + + /* Ensure strbuf can handle a string length bytes long (ignoring NULL + * optional termination). */ +-void strbuf_resize(strbuf_t *s, int len) ++void strbuf_resize(strbuf_t *s, size_t len) + { +- int newsize; ++ size_t newsize; + + newsize = calculate_new_size(s, len); + + if (s->debug > 1) { +- fprintf(stderr, "strbuf(%lx) resize: %d => %d\n", ++ fprintf(stderr, "strbuf(%lx) resize: %zd => %zd\n", + (long)s, s->size, newsize); + } + + s->size = newsize; + s->buf = realloc(s->buf, s->size); + if (!s->buf) +- die("Out of memory"); ++ die("Out of memory, len: %zu", len); + s->reallocs++; + } + + void strbuf_append_string(strbuf_t *s, const char *str) + { +- int space, i; ++ int i; ++ size_t space; + + space = strbuf_empty_length(s); + +@@ -197,55 +193,6 @@ void strbuf_append_string(strbuf_t *s, const char *str) + } + } + +-/* strbuf_append_fmt() should only be used when an upper bound +- * is known for the output string. */ +-void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...) +-{ +- va_list arg; +- int fmt_len; +- +- strbuf_ensure_empty_length(s, len); +- +- va_start(arg, fmt); +- fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg); +- va_end(arg); +- +- if (fmt_len < 0) +- die("BUG: Unable to convert number"); /* This should never happen.. */ +- +- s->length += fmt_len; +-} +- +-/* strbuf_append_fmt_retry() can be used when the there is no known +- * upper bound for the output string. */ +-void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...) +-{ +- va_list arg; +- int fmt_len, try; +- int empty_len; +- +- /* If the first attempt to append fails, resize the buffer appropriately +- * and try again */ +- for (try = 0; ; try++) { +- va_start(arg, fmt); +- /* Append the new formatted string */ +- /* fmt_len is the length of the string required, excluding the +- * trailing NULL */ +- empty_len = strbuf_empty_length(s); +- /* Add 1 since there is also space to store the terminating NULL. */ +- fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg); +- va_end(arg); +- +- if (fmt_len <= empty_len) +- break; /* SUCCESS */ +- if (try > 0) +- die("BUG: length of formatted string changed"); +- +- strbuf_resize(s, s->length + fmt_len); +- } +- +- s->length += fmt_len; +-} + + /* vi:ai et sw=4 ts=4: + */ +diff --git a/deps/lua/src/strbuf.h b/deps/lua/src/strbuf.h +index d861108c14cd..c10f83f0db89 100644 +--- a/deps/lua/src/strbuf.h ++++ b/deps/lua/src/strbuf.h +@@ -27,15 +27,13 @@ + + /* Size: Total bytes allocated to *buf + * Length: String length, excluding optional NULL terminator. +- * Increment: Allocation increments when resizing the string buffer. + * Dynamic: True if created via strbuf_new() + */ + + typedef struct { + char *buf; +- int size; +- int length; +- int increment; ++ size_t size; ++ size_t length; + int dynamic; + int reallocs; + int debug; +@@ -44,32 +42,26 @@ typedef struct { + #ifndef STRBUF_DEFAULT_SIZE + #define STRBUF_DEFAULT_SIZE 1023 + #endif +-#ifndef STRBUF_DEFAULT_INCREMENT +-#define STRBUF_DEFAULT_INCREMENT -2 +-#endif + + /* Initialise */ +-extern strbuf_t *strbuf_new(int len); +-extern void strbuf_init(strbuf_t *s, int len); +-extern void strbuf_set_increment(strbuf_t *s, int increment); ++extern strbuf_t *strbuf_new(size_t len); ++extern void strbuf_init(strbuf_t *s, size_t len); + + /* Release */ + extern void strbuf_free(strbuf_t *s); +-extern char *strbuf_free_to_string(strbuf_t *s, int *len); ++extern char *strbuf_free_to_string(strbuf_t *s, size_t *len); + + /* Management */ +-extern void strbuf_resize(strbuf_t *s, int len); +-static int strbuf_empty_length(strbuf_t *s); +-static int strbuf_length(strbuf_t *s); +-static char *strbuf_string(strbuf_t *s, int *len); +-static void strbuf_ensure_empty_length(strbuf_t *s, int len); ++extern void strbuf_resize(strbuf_t *s, size_t len); ++static size_t strbuf_empty_length(strbuf_t *s); ++static size_t strbuf_length(strbuf_t *s); ++static char *strbuf_string(strbuf_t *s, size_t *len); ++static void strbuf_ensure_empty_length(strbuf_t *s, size_t len); + static char *strbuf_empty_ptr(strbuf_t *s); +-static void strbuf_extend_length(strbuf_t *s, int len); ++static void strbuf_extend_length(strbuf_t *s, size_t len); + + /* Update */ +-extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...); +-extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...); +-static void strbuf_append_mem(strbuf_t *s, const char *c, int len); ++static void strbuf_append_mem(strbuf_t *s, const char *c, size_t len); + extern void strbuf_append_string(strbuf_t *s, const char *str); + static void strbuf_append_char(strbuf_t *s, const char c); + static void strbuf_ensure_null(strbuf_t *s); +@@ -87,12 +79,12 @@ static inline int strbuf_allocated(strbuf_t *s) + + /* Return bytes remaining in the string buffer + * Ensure there is space for a NULL terminator. */ +-static inline int strbuf_empty_length(strbuf_t *s) ++static inline size_t strbuf_empty_length(strbuf_t *s) + { + return s->size - s->length - 1; + } + +-static inline void strbuf_ensure_empty_length(strbuf_t *s, int len) ++static inline void strbuf_ensure_empty_length(strbuf_t *s, size_t len) + { + if (len > strbuf_empty_length(s)) + strbuf_resize(s, s->length + len); +@@ -103,12 +95,12 @@ static inline char *strbuf_empty_ptr(strbuf_t *s) + return s->buf + s->length; + } + +-static inline void strbuf_extend_length(strbuf_t *s, int len) ++static inline void strbuf_extend_length(strbuf_t *s, size_t len) + { + s->length += len; + } + +-static inline int strbuf_length(strbuf_t *s) ++static inline size_t strbuf_length(strbuf_t *s) + { + return s->length; + } +@@ -124,14 +116,14 @@ static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c) + s->buf[s->length++] = c; + } + +-static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len) ++static inline void strbuf_append_mem(strbuf_t *s, const char *c, size_t len) + { + strbuf_ensure_empty_length(s, len); + memcpy(s->buf + s->length, c, len); + s->length += len; + } + +-static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len) ++static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, size_t len) + { + memcpy(s->buf + s->length, c, len); + s->length += len; +@@ -142,7 +134,7 @@ static inline void strbuf_ensure_null(strbuf_t *s) + s->buf[s->length] = 0; + } + +-static inline char *strbuf_string(strbuf_t *s, int *len) ++static inline char *strbuf_string(strbuf_t *s, size_t *len) + { + if (len) + *len = s->length; +diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl +index 8314f0268f41..552ed757a711 100644 +--- a/tests/unit/scripting.tcl ++++ b/tests/unit/scripting.tcl +@@ -215,6 +215,66 @@ start_server {tags {"scripting"}} { + } 0 + } {a b} + ++ test {EVAL - JSON smoke test} { ++ r eval { ++ local some_map = { ++ s1="Some string", ++ n1=100, ++ a1={"Some","String","Array"}, ++ nil1=nil, ++ b1=true, ++ b2=false} ++ local encoded = cjson.encode(some_map) ++ local decoded = cjson.decode(encoded) ++ assert(table.concat(some_map) == table.concat(decoded)) ++ ++ cjson.encode_keep_buffer(false) ++ encoded = cjson.encode(some_map) ++ decoded = cjson.decode(encoded) ++ assert(table.concat(some_map) == table.concat(decoded)) ++ ++ -- Table with numeric keys ++ local table1 = {one="one", [1]="one"} ++ encoded = cjson.encode(table1) ++ decoded = cjson.decode(encoded) ++ assert(decoded["one"] == table1["one"]) ++ assert(decoded["1"] == table1[1]) ++ ++ -- Array ++ local array1 = {[1]="one", [2]="two"} ++ encoded = cjson.encode(array1) ++ decoded = cjson.decode(encoded) ++ assert(table.concat(array1) == table.concat(decoded)) ++ ++ -- Invalid keys ++ local invalid_map = {} ++ invalid_map[false] = "false" ++ local ok, encoded = pcall(cjson.encode, invalid_map) ++ assert(ok == false) ++ ++ -- Max depth ++ cjson.encode_max_depth(1) ++ ok, encoded = pcall(cjson.encode, some_map) ++ assert(ok == false) ++ ++ cjson.decode_max_depth(1) ++ ok, decoded = pcall(cjson.decode, '{"obj": {"array": [1,2,3,4]}}') ++ assert(ok == false) ++ ++ -- Invalid numbers ++ ok, encoded = pcall(cjson.encode, {num1=0/0}) ++ assert(ok == false) ++ cjson.encode_invalid_numbers(true) ++ ok, encoded = pcall(cjson.encode, {num1=0/0}) ++ assert(ok == true) ++ ++ -- Restore defaults ++ cjson.decode_max_depth(1000) ++ cjson.encode_max_depth(1000) ++ cjson.encode_invalid_numbers(false) ++ } 0 ++ } ++ + test {EVAL - cmsgpack can pack double?} { + r eval {local encoded = cmsgpack.pack(0.1) + local h = "" +@@ -235,6 +295,68 @@ start_server {tags {"scripting"}} { + } 0 + } {d3ffffff0000000000} + ++ test {EVAL - cmsgpack pack/unpack smoke test} { ++ r eval { ++ local str_lt_32 = string.rep("x", 30) ++ local str_lt_255 = string.rep("x", 250) ++ local str_lt_65535 = string.rep("x", 65530) ++ local str_long = string.rep("x", 100000) ++ local array_lt_15 = {1, 2, 3, 4, 5} ++ local array_lt_65535 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} ++ local array_big = {} ++ for i=1, 100000 do ++ array_big[i] = i ++ end ++ local map_lt_15 = {a=1, b=2} ++ local map_big = {} ++ for i=1, 100000 do ++ map_big[tostring(i)] = i ++ end ++ local some_map = { ++ s1=str_lt_32, ++ s2=str_lt_255, ++ s3=str_lt_65535, ++ s4=str_long, ++ d1=0.1, ++ i1=1, ++ i2=250, ++ i3=65530, ++ i4=100000, ++ i5=2^40, ++ i6=-1, ++ i7=-120, ++ i8=-32000, ++ i9=-100000, ++ i10=-3147483648, ++ a1=array_lt_15, ++ a2=array_lt_65535, ++ a3=array_big, ++ m1=map_lt_15, ++ m2=map_big, ++ b1=false, ++ b2=true, ++ n=nil ++ } ++ local encoded = cmsgpack.pack(some_map) ++ local decoded = cmsgpack.unpack(encoded) ++ assert(table.concat(some_map) == table.concat(decoded)) ++ local offset, decoded_one = cmsgpack.unpack_one(encoded, 0) ++ assert(table.concat(some_map) == table.concat(decoded_one)) ++ assert(offset == -1) ++ ++ local encoded_multiple = cmsgpack.pack(str_lt_32, str_lt_255, str_lt_65535, str_long) ++ local offset, obj = cmsgpack.unpack_limit(encoded_multiple, 1, 0) ++ assert(obj == str_lt_32) ++ offset, obj = cmsgpack.unpack_limit(encoded_multiple, 1, offset) ++ assert(obj == str_lt_255) ++ offset, obj = cmsgpack.unpack_limit(encoded_multiple, 1, offset) ++ assert(obj == str_lt_65535) ++ offset, obj = cmsgpack.unpack_limit(encoded_multiple, 1, offset) ++ assert(obj == str_long) ++ assert(offset == -1) ++ } 0 ++ } ++ + test {EVAL - cmsgpack can pack and unpack circular references?} { + r eval {local a = {x=nil,y=5} + local b = {x=a} +@@ -396,6 +518,7 @@ start_server {tags {"scripting"}} { + } + + test {EVAL does not leak in the Lua stack} { ++ r script flush ;# reset Lua VM + r set x 0 + # Use a non blocking client to speedup the loop. + set rd [redis_deferring_client] diff --git a/CVE-2022-36021.patch b/CVE-2022-36021.patch new file mode 100644 index 0000000..0eb5b30 --- /dev/null +++ b/CVE-2022-36021.patch @@ -0,0 +1,92 @@ +From dcbfcb916ca1a269b3feef86ee86835294758f84 Mon Sep 17 00:00:00 2001 +From: Oran Agra <oran@redislabs.com> +Date: Tue, 28 Feb 2023 15:15:26 +0200 +Subject: [PATCH] String pattern matching had exponential time complexity on + pathological patterns (CVE-2022-36021) (#11858) + +Authenticated users can use string matching commands with a +specially crafted pattern to trigger a denial-of-service attack on Redis, +causing it to hang and consume 100% CPU time. + +Co-authored-by: Tom Levy <tomlevy93@gmail.com> +--- + src/util.c | 27 +++++++++++++++++++++++---- + tests/unit/keyspace.tcl | 6 ++++++ + 2 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/src/util.c b/src/util.c +index d33f4522a507..26d92b92290e 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -44,8 +44,8 @@ + #include "sha1.h" + + /* Glob-style pattern matching. */ +-int stringmatchlen(const char *pattern, int patternLen, +- const char *string, int stringLen, int nocase) ++static int stringmatchlen_impl(const char *pattern, int patternLen, ++ const char *string, int stringLen, int nocase, int *skipLongerMatches) + { + while(patternLen && stringLen) { + switch(pattern[0]) { +@@ -57,12 +57,24 @@ + if (patternLen == 1) + return 1; /* match */ + while(stringLen) { +- if (stringmatchlen(pattern+1, patternLen-1, +- string, stringLen, nocase)) ++ if (stringmatchlen_impl(pattern+1, patternLen-1, ++ string, stringLen, nocase, skipLongerMatches)) + return 1; /* match */ ++ if (*skipLongerMatches) ++ return 0; /* no match */ + string++; + stringLen--; + } ++ /* There was no match for the rest of the pattern starting ++ * from anywhere in the rest of the string. If there were ++ * any '*' earlier in the pattern, we can terminate the ++ * search early without trying to match them to longer ++ * substrings. This is because a longer match for the ++ * earlier part of the pattern would require the rest of the ++ * pattern to match starting later in the string, and we ++ * have just determined that there is no match for the rest ++ * of the pattern starting from anywhere in the current ++ * string. */ + return 0; /* no match */ + break; + case '?': +@@ -166,10 +178,17 @@ + return 0; + } + ++int stringmatchlen(const char *pattern, int patternLen, ++ const char *string, int stringLen, int nocase) { ++ int skipLongerMatches = 0; ++ return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches); ++} ++ + int stringmatch(const char *pattern, const char *string, int nocase) { + return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase); + } + ++ + /* Convert a string representing an amount of memory into the number of + * bytes, so for instance memtoll("1Gb") will return 1073741824 that is + * (1024*1024*1024). + +diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl +index b173e0efcacc..43690d06b321 100644 +--- a/tests/unit/keyspace.tcl ++++ b/tests/unit/keyspace.tcl +@@ -493,4 +493,10 @@ foreach {type large} [array get largevalue] { + r keys * + r keys * + } {dlskeriewrioeuwqoirueioqwrueoqwrueqw} ++ ++ test {Regression for pattern matching long nested loops} { ++ r flushdb ++ r SET aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 ++ r KEYS "a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*b" ++ } {} + } diff --git a/CVE-2023-28856.patch b/CVE-2023-28856.patch new file mode 100644 index 0000000..43ceb81 --- /dev/null +++ b/CVE-2023-28856.patch @@ -0,0 +1,49 @@ +From c924ac3fdf8fe544891dc66c88018e259ee4be87 Mon Sep 17 00:00:00 2001 +From: chendianqiang <c.d_q@163.com> +Date: Sun, 28 Aug 2022 16:33:41 +0800 +Subject: [PATCH] fix hincrbyfloat not to create a key if the new value is + invalid (#11149) + +Check the validity of the value before performing the create operation, +prevents new data from being generated even if the request fails to execute. + +Co-authored-by: Oran Agra <oran@redislabs.com> +Co-authored-by: chendianqiang <chendianqiang@meituan.com> +Co-authored-by: Binbin <binloveplay1314@qq.com> +(cherry picked from commit bc7fe41e5857a0854d524e2a63a028e9394d2a5c) +(cherry picked from commit 606a385935363ea46c0df4f40f8a949d85f7a20a) +(cherry picked from commit 7df23a5f51488ce002411c9d24b38520ad67b764) +--- + src/t_hash.c | 4 ++++ + tests/unit/type/hash.tcl | 5 +++++ + 2 files changed, 9 insertions(+) + +diff --git a/src/t_hash.c b/src/t_hash.c +index 3cdfdd169abf..13e65502f145 100644 +--- a/src/t_hash.c ++++ b/src/t_hash.c +@@ -605,6 +605,10 @@ void hincrbyfloatCommand(client *c) { + unsigned int vlen; + + if (getLongDoubleFromObjectOrReply(c,c->argv[3],&incr,NULL) != C_OK) return; ++ if (isnan(incr) || isinf(incr)) { ++ addReplyError(c,"value is NaN or Infinity"); ++ return; ++ } + if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return; + if (hashTypeGetValue(o,c->argv[2]->ptr,&vstr,&vlen,&ll) == C_OK) { + if (vstr) { +diff --git a/tests/unit/type/hash.tcl b/tests/unit/type/hash.tcl +index 9f8a21b1ce11..931662989d82 100644 +--- a/tests/unit/type/hash.tcl ++++ b/tests/unit/type/hash.tcl +@@ -540,4 +540,9 @@ start_server {tags {"hash"}} { + assert {[r hincrbyfloat myhash float -0.1] eq {1.9}} + } + } ++ ++ test {HINCRBYFLOAT does not allow NaN or Infinity} { ++ assert_error "*value is NaN or Infinity*" {r hincrbyfloat hfoo field +inf} ++ assert_equal 0 [r exists hfoo] ++ } + } diff --git a/CVE-2023-45145.patch b/CVE-2023-45145.patch new file mode 100644 index 0000000..96e4b17 --- /dev/null +++ b/CVE-2023-45145.patch @@ -0,0 +1,66 @@ +From 7f486ea6eebf0afce74f2e59763b9b82b78629dc Mon Sep 17 00:00:00 2001 +From: Yossi Gottlieb <yossigo@gmail.com> +Date: Wed, 11 Oct 2023 22:45:34 +0300 +Subject: [PATCH] Fix issue of listen before chmod on Unix sockets + (CVE-2023-45145) + +Before this commit, Unix socket setup performed chmod(2) on the socket +file after calling listen(2). Depending on what umask is used, this +could leave the file with the wrong permissions for a short period of +time. As a result, another process could exploit this race condition and +establish a connection that would otherwise not be possible. + +We now make sure the socket permissions are set up prior to calling +listen(2). + +(cherry picked from commit a11b3bc34a054818f2ac70e50adfc542ca1cba42) +--- + src/anet.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/anet.c b/src/anet.c +index dc88eb7..d0db80f 100644 +--- a/src/anet.c ++++ b/src/anet.c +@@ -437,13 +437,16 @@ int anetWrite(int fd, char *buf, int count) + return totlen; + } + +-static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) { ++static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) { + if (bind(s,sa,len) == -1) { + anetSetError(err, "bind: %s", strerror(errno)); + close(s); + return ANET_ERR; + } + ++ if (sa->sa_family == AF_LOCAL && perm) ++ chmod(((struct sockaddr_un *) sa)->sun_path, perm); ++ + if (listen(s, backlog) == -1) { + anetSetError(err, "listen: %s", strerror(errno)); + close(s); +@@ -484,7 +487,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl + + if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error; + if (anetSetReuseAddr(err,s) == ANET_ERR) goto error; +- if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR; ++ if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR; + goto end; + } + if (p == NULL) { +@@ -521,10 +524,8 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog) + memset(&sa,0,sizeof(sa)); + sa.sun_family = AF_LOCAL; + strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1); +- if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog) == ANET_ERR) ++ if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR) + return ANET_ERR; +- if (perm) +- chmod(sa.sun_path, perm); + return s; + } + +-- +2.33.0 + diff --git a/CVE-2024-31228.patch b/CVE-2024-31228.patch new file mode 100644 index 0000000..eae6831 --- /dev/null +++ b/CVE-2024-31228.patch @@ -0,0 +1,63 @@ +From c8649f8e852d1dc388b5446e003bb0eefa33d61f Mon Sep 17 00:00:00 2001 +From: Oran Agra <oran@redislabs.com> +Date: Wed, 2 Oct 2024 20:11:01 +0300 +Subject: [PATCH] Prevent pattern matching abuse (CVE-2024-31228) + +--- + src/util.c | 9 ++++++--- + tests/unit/keyspace.tcl | 6 ++++++ + 2 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/util.c b/src/util.c +index 861ef67..0f5e8e1 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -45,8 +45,11 @@ + + /* Glob-style pattern matching. */ + static int stringmatchlen_impl(const char *pattern, int patternLen, +- const char *string, int stringLen, int nocase, int *skipLongerMatches) ++ const char *string, int stringLen, int nocase, int *skipLongerMatches, int nesting) + { ++ /* Protection against abusive patterns. */ ++ if (nesting > 1000) return 0; ++ + while(patternLen && stringLen) { + switch(pattern[0]) { + case '*': +@@ -58,7 +61,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen, + return 1; /* match */ + while(stringLen) { + if (stringmatchlen_impl(pattern+1, patternLen-1, +- string, stringLen, nocase, skipLongerMatches)) ++ string, stringLen, nocase, skipLongerMatches, nesting+1)) + return 1; /* match */ + if (*skipLongerMatches) + return 0; /* no match */ +@@ -181,7 +184,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen, + int stringmatchlen(const char *pattern, int patternLen, + const char *string, int stringLen, int nocase) { + int skipLongerMatches = 0; +- return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches); ++ return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches,0); + } + + int stringmatch(const char *pattern, const char *string, int nocase) { +diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl +index 1617ac5..2217b29 100644 +--- a/tests/unit/keyspace.tcl ++++ b/tests/unit/keyspace.tcl +@@ -278,4 +278,10 @@ start_server {tags {"keyspace"}} { + r SET aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 + r KEYS "a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*b" + } {} ++ ++ test {Regression for pattern matching very long nested loops} { ++ r flushdb ++ r SET [string repeat "a" 50000] 1 ++ r KEYS [string repeat "*?" 50000] ++ } {} + } +-- +2.33.0 + diff --git a/CVE-2024-31449.patch b/CVE-2024-31449.patch new file mode 100644 index 0000000..4fde3b7 --- /dev/null +++ b/CVE-2024-31449.patch @@ -0,0 +1,43 @@ +From fe8de4313f85e0f8af2eff1f78b52cfe56fb4c71 Mon Sep 17 00:00:00 2001 +From: Oran Agra <oran@redislabs.com> +Date: Wed, 2 Oct 2024 19:54:06 +0300 +Subject: [PATCH] Fix lua bit.tohex (CVE-2024-31449) + +INT_MIN value must be explicitly checked, and cannot be negated. +--- + deps/lua/src/lua_bit.c | 1 + + tests/unit/scripting.tcl | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/deps/lua/src/lua_bit.c b/deps/lua/src/lua_bit.c +index 690df7d..a459ca9 100644 +--- a/deps/lua/src/lua_bit.c ++++ b/deps/lua/src/lua_bit.c +@@ -131,6 +131,7 @@ static int bit_tohex(lua_State *L) + const char *hexdigits = "0123456789abcdef"; + char buf[8]; + int i; ++ if (n == INT32_MIN) n = INT32_MIN+1; + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } + if (n > 8) n = 8; + for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } +diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl +index d747fa6..a7e1e9e 100644 +--- a/tests/unit/scripting.tcl ++++ b/tests/unit/scripting.tcl +@@ -459,6 +459,12 @@ start_server {tags {"scripting"}} { + set e + } {*ERR*attempted to create global*} + ++ test {lua bit.tohex bug} { ++ set res [run_script {return bit.tohex(65535, -2147483648)} 0] ++ r ping ++ set res ++ } {0000FFFF} ++ + test {Test an example script DECR_IF_GT} { + set decr_if_gt { + local current +-- +2.33.0 + @@ -1,28 +1,30 @@ Name: redis -Version: 4.0.11 -Release: 18 +Version: 5.0.4 +Release: 7 Summary: A persistent key-value database -License: BSD and MIT +License: BSD-3-Clause and MIT URL: https://redis.io Source0: http://download.redis.io/releases/%{name}-%{version}.tar.gz Source1: %{name}.logrotate Source2: %{name}-sentinel.service Source3: %{name}.service -#CVE fix -Patch0001: CVE-2019-10192-1.patch -#Optimization of the above problem -Patch0002: CVE-2019-10192-2.patch -Patch0003: CVE-2020-14147.patch -Patch0004: improved-HyperLogLog-cardinality-estimation.patch -Patch0005: Aesthetic-changes-to-PR.patch -Patch0006: CVE-2019-10193.patch -Patch0007: modify-aarch64-architecture-jemalloc-page-size-from-4k-to-64k.patch -Patch0008: huawei-deps-jemalloc-support-riscv.patch -Patch0009: CVE-2021-21309.patch -Patch0010: CVE-2021-3470.patch -Patch0011: CVE-2021-29478.patch -Patch0012: CVE-2021-32672.patch +Patch0001: CVE-2020-14147.patch +Patch0002: improved-HyperLogLog-cardinality-estimation.patch +Patch0003: Aesthetic-changes-to-PR.patch +Patch0004: CVE-2019-10193.patch +Patch0005: modify-aarch64-architecture-jemalloc-page-size-from-4k-to-64k.patch +Patch0006: huawei-deps-jemalloc-support-riscv.patch +Patch0007: CVE-2021-21309.patch +Patch0008: CVE-2021-3470.patch +Patch0009: CVE-2021-29478.patch +Patch0010: CVE-2021-32672.patch +Patch0011: CVE-2022-36021.patch +Patch0012: CVE-2023-28856.patch +Patch0013: CVE-2022-24834.patch +Patch0014: CVE-2023-45145.patch +Patch0015: CVE-2024-31228.patch +Patch0016: CVE-2024-31449.patch BuildRequires: systemd gcc Requires: /bin/awk @@ -42,16 +44,24 @@ Redis is an advanced key-value store. It is often referred to as a dattructure s %patch0002 -p1 %patch0003 -p1 %patch0004 -p1 +%ifarch aarch64 %patch0005 -p1 +%endif %patch0006 -p1 -%ifarch aarch64 %patch0007 -p1 -%endif %patch0008 -p1 %patch0009 -p1 %patch0010 -p1 %patch0011 -p1 %patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 +%patch0015 -p1 +%patch0016 -p1 +%ifarch loongarch64 +%_update_config_guess +%_update_config_sub +%endif sed -i -e 's|^logfile .*$|logfile /var/log/redis/redis.log|g' redis.conf sed -i -e '$ alogfile /var/log/redis/sentinel.log' sentinel.conf @@ -109,6 +119,27 @@ exit 0 %{_unitdir}/%{name}-sentinel.service %changelog +* Wed Oct 09 2024 yaoxin <yao_xin001@hoperun.com> - 4.0.14-7 +- Fix CVE-2023-45145,CVE-2024-31228 and CVE-2024-31449 + +* Mon Jul 31 2023 wangkai <13474090681@163.com> - 4.0.14-6 +- Fix CVE-2022-24834 + +* Mon May 15 2023 yaoxin <yao_xin001@hoperun.com> - 4.0.14-5 +- Fix CVE-2023-28856 + +* Mon Mar 27 2023 wushaozheng<wushaozheng@ncti-gba.cn> - 4.0.14-4 +- Fix CVE-2022-36021 + +* Tue Nov 15 2022 huajingyun<huajingyun@loongson.cn> - 4.0.14-3 +- Update config.guess and config.sub for loongarch + +* Tue May 10 2022 chenchen <chen_aka_jan@163.com> - 4.0.14-2 +- License compliance rectification + +* Wed Dec 29 2021 zhangjiapeng <zhangjiapeng9@huawei.com> - 4.0.14-1 +- Update to 4.0.14 + * Sat Oct 09 2021 yaoxin <yaoxin30@huawei.com> - 4.0.11-18 - Fix CVE-2021-32672 @@ -1 +1 @@ -e62d3793f86a6a0021609c9f905cb960 redis-4.0.11.tar.gz +f63b54574c5211b77406001352b7de99 redis-5.0.4.tar.gz |