From f5d84aad5bc485dbb9299d6da3f6b8f366f73244 Mon Sep 17 00:00:00 2001 From: shaominghao Date: Thu, 21 Dec 2023 17:23:58 +0800 Subject: [PATCH 1/2] Backport to fix CVE-2023-25155 Signed-off-by: shaominghao --- backport-refactor-CVE-2023-25155.patch | 129 +++++++++++++++++++++++++ redis5.spec | 7 +- 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 backport-refactor-CVE-2023-25155.patch diff --git a/backport-refactor-CVE-2023-25155.patch b/backport-refactor-CVE-2023-25155.patch new file mode 100644 index 0000000..c3a4d3c --- /dev/null +++ b/backport-refactor-CVE-2023-25155.patch @@ -0,0 +1,129 @@ +From 68e785e04053619eac9364485c2c72bbcc0a5f0f Mon Sep 17 00:00:00 2001 +From: shaominghao +Date: Thu, 21 Dec 2023 16:27:16 +0800 +Subject: [PATCH] backport-refactor-CVE-2023-25155 + +--- + src/debug.c | 6 +++++- + src/object.c | 18 ++++++++++++++++++ + src/server.h | 3 +++ + src/t_set.c | 3 ++- + tests/unit/type/set.tcl | 6 ++++++ + 5 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/src/debug.c b/src/debug.c +index 351d749..2a14a48 100644 +--- a/src/debug.c ++++ b/src/debug.c +@@ -478,9 +478,12 @@ NULL + robj *key, *val; + char buf[128]; + +- if (getLongFromObjectOrReply(c, c->argv[2], &keys, NULL) != C_OK) ++ if (getPositiveLongFromObjectOrReply(c, c->argv[2], &keys, NULL) != C_OK) + return; + dictExpand(c->db->dict,keys); ++ long valsize = 0; ++ if ( c->argc == 5 && getPositiveLongFromObjectOrReply(c, c->argv[4], &valsize, NULL) != C_OK ) ++ return; + for (j = 0; j < keys; j++) { + long valsize = 0; + snprintf(buf,sizeof(buf),"%s:%lu", +@@ -1444,3 +1447,4 @@ void disableWatchdog(void) { + sigaction(SIGALRM, &act, NULL); + server.watchdog_period = 0; + } ++ +diff --git a/src/object.c b/src/object.c +index 58f9162..99e4459 100644 +--- a/src/object.c ++++ b/src/object.c +@@ -737,6 +737,23 @@ int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg) + return C_OK; + } + ++int getRangeLongFromObjectOrReply(client *c, robj *o, long min, long max, long *target, const char *msg) { ++ if (getLongFromObjectOrReply(c, o, target, msg) != C_OK) return C_ERR; ++ if (*target < min || *target > max) { ++ if (msg != NULL) { ++ addReplyError(c,(char*)msg); ++ } else { ++ addReplyErrorFormat(c,"value is out of range, value must between %ld and %ld", min, max); ++ } ++ return C_ERR; ++ } ++ return C_OK; ++} ++ ++int getPositiveLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg) { ++ return getRangeLongFromObjectOrReply(c, o, 0, LONG_MAX, target, msg); ++} ++ + char *strEncoding(int encoding) { + switch(encoding) { + case OBJ_ENCODING_RAW: return "raw"; +@@ -1468,3 +1485,4 @@ NULL + addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try MEMORY HELP", (char*)c->argv[1]->ptr); + } + } ++ +diff --git a/src/server.h b/src/server.h +index 164a822..18c00f4 100644 +--- a/src/server.h ++++ b/src/server.h +@@ -1575,6 +1575,8 @@ robj *createZsetZiplistObject(void); + robj *createStreamObject(void); + robj *createModuleObject(moduleType *mt, void *value); + int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg); ++int getPositiveLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg); ++int getRangeLongFromObjectOrReply(client *c, robj *o, long min, long max, long *target, const char *msg); + int checkType(client *c, robj *o, int type); + int getLongLongFromObjectOrReply(client *c, robj *o, long long *target, const char *msg); + int getDoubleFromObjectOrReply(client *c, robj *o, double *target, const char *msg); +@@ -2182,3 +2184,4 @@ void xorDigest(unsigned char *digest, void *ptr, size_t len); + printf("-- MARK %s:%d --\n", __FILE__, __LINE__) + + #endif ++ +diff --git a/src/t_set.c b/src/t_set.c +index db5a8cb..99f3e11 100644 +--- a/src/t_set.c ++++ b/src/t_set.c +@@ -408,7 +408,7 @@ void spopWithCountCommand(client *c) { + robj *set; + + /* Get the count argument */ +- if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return; ++ if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return; + if (l >= 0) { + count = (unsigned long) l; + } else { +@@ -1116,3 +1116,4 @@ void sscanCommand(client *c) { + checkType(c,set,OBJ_SET)) return; + scanGenericCommand(c,set,cursor); + } ++ +diff --git a/tests/unit/type/set.tcl b/tests/unit/type/set.tcl +index 7b467f1..d1726f2 100644 +--- a/tests/unit/type/set.tcl ++++ b/tests/unit/type/set.tcl +@@ -377,6 +377,11 @@ start_server { + r srandmember nonexisting_key 100 + } {} + ++ test "SRANDMEMBER count overflow" { ++ r sadd myset a ++ assert_error {*value is out of range*} {r srandmember myset -9223372036854775808} ++ } {} ++ + foreach {type contents} { + hashtable { + 1 5 10 50 125 50000 33959417 4775547 65434162 +@@ -599,3 +604,4 @@ start_server { + } + } + } ++ +-- +2.27.0 + diff --git a/redis5.spec b/redis5.spec index 16c0ab4..603b595 100644 --- a/redis5.spec +++ b/redis5.spec @@ -6,7 +6,7 @@ %global Pname redis Name: redis5 Version: 5.0.14 -Release: 2 +Release: 3 Summary: A persistent key-value database License: BSD and MIT URL: https://redis.io @@ -24,6 +24,7 @@ Source10: https://github.com/antirez/%{Pname}-doc/archive/%{doc_commi Patch0001: Modify-aarch64-architecture-jemalloc-page-size-from-from-4k-to-64k.patch Patch0002: Fix-display-error-message.patch +Patch0003: backport-refactor-CVE-2023-25155.patch BuildRequires: gcc %if %{with tests} @@ -85,6 +86,7 @@ tar -xvf %{SOURCE10} %patch0001 -p1 %endif %patch0002 -p1 +%patch0003 -p1 mv ../%{Pname}-doc-%{doc_commit} doc mv deps/lua/COPYRIGHT COPYRIGHT-lua mv deps/hiredis/COPYING COPYING-hiredis @@ -189,6 +191,9 @@ exit 0 %{_docdir}/%{Pname} %changelog +* Thu Dec 21 2023 shaominghao - 5.0.14-3 +- backport-refactor-CVE-2023-25155 + * Sat Dec 04 2021 xu_ping - 5.0.14-2 - Fix display error message -- Gitee From 5a918d66216837071184b3c24bacfff2b7fccb13 Mon Sep 17 00:00:00 2001 From: shaominghao Date: Fri, 22 Dec 2023 10:13:21 +0800 Subject: [PATCH 2/2] Fix CVE-2023-45145 Signed-off-by: shaominghao --- backport-CVE-2023-45145.patch | 60 +++++++++++++++++++++++++++++++++++ redis5.spec | 7 +++- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2023-45145.patch diff --git a/backport-CVE-2023-45145.patch b/backport-CVE-2023-45145.patch new file mode 100644 index 0000000..fe4abd0 --- /dev/null +++ b/backport-CVE-2023-45145.patch @@ -0,0 +1,60 @@ +From 3585f8cd111c09a58d9e811a17c4f37baee25b85 Mon Sep 17 00:00:00 2001 +From: shaominghao +Date: Thu, 21 Dec 2023 16:43:32 +0800 +Subject: [PATCH] Fix issue of listen before chmod on Unix sockets + +--- + src/anet.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/anet.c b/src/anet.c +index 2981fca..739a675 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; + } + +@@ -656,3 +657,4 @@ int anetFormatSock(int fd, char *fmt, size_t fmt_len) { + anetSockName(fd,ip,sizeof(ip),&port); + return anetFormatAddr(fmt, fmt_len, ip, port); + } ++ +-- +2.27.0 + diff --git a/redis5.spec b/redis5.spec index 603b595..f372914 100644 --- a/redis5.spec +++ b/redis5.spec @@ -6,7 +6,7 @@ %global Pname redis Name: redis5 Version: 5.0.14 -Release: 3 +Release: 4 Summary: A persistent key-value database License: BSD and MIT URL: https://redis.io @@ -25,6 +25,7 @@ Source10: https://github.com/antirez/%{Pname}-doc/archive/%{doc_commi Patch0001: Modify-aarch64-architecture-jemalloc-page-size-from-from-4k-to-64k.patch Patch0002: Fix-display-error-message.patch Patch0003: backport-refactor-CVE-2023-25155.patch +Patch0004: backport-CVE-2023-45145.patch BuildRequires: gcc %if %{with tests} @@ -87,6 +88,7 @@ tar -xvf %{SOURCE10} %endif %patch0002 -p1 %patch0003 -p1 +%patch0004 -p1 mv ../%{Pname}-doc-%{doc_commit} doc mv deps/lua/COPYRIGHT COPYRIGHT-lua mv deps/hiredis/COPYING COPYING-hiredis @@ -191,6 +193,9 @@ exit 0 %{_docdir}/%{Pname} %changelog +* Fri Dec 22 2023 shaominghao - 5.0.14-4 +- Fix CVE-2023-45145 + * Thu Dec 21 2023 shaominghao - 5.0.14-3 - backport-refactor-CVE-2023-25155 -- Gitee