summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CVE-2019-10192-1.patch33
-rw-r--r--CVE-2019-10192-2.patch35
-rw-r--r--CVE-2022-24834.patch689
-rw-r--r--CVE-2022-36021.patch92
-rw-r--r--CVE-2023-28856.patch49
-rw-r--r--CVE-2023-45145.patch66
-rw-r--r--CVE-2024-31228.patch63
-rw-r--r--CVE-2024-31449.patch43
-rw-r--r--redis.spec69
-rw-r--r--sources2
11 files changed, 1054 insertions, 88 deletions
diff --git a/.gitignore b/.gitignore
index b8019be..822bb64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
+
diff --git a/redis.spec b/redis.spec
index 60ecf33..75da5eb 100644
--- a/redis.spec
+++ b/redis.spec
@@ -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
diff --git a/sources b/sources
index 0b5abe8..bd5392a 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-e62d3793f86a6a0021609c9f905cb960 redis-4.0.11.tar.gz
+f63b54574c5211b77406001352b7de99 redis-5.0.4.tar.gz