diff --git a/3-bugfix-for-CVE-2025-48367.patch b/3-bugfix-for-CVE-2025-48367.patch deleted file mode 100644 index 9a5b3e2094bfc952700a9699c0904bff71cb4600..0000000000000000000000000000000000000000 --- a/3-bugfix-for-CVE-2025-48367.patch +++ /dev/null @@ -1,111 +0,0 @@ -From bde62951accfc4bb0a516276fd0b4b307e140ce2 Mon Sep 17 00:00:00 2001 -From: Ozan Tezcan -Date: Wed, 14 May 2025 11:02:30 +0300 -Subject: [PATCH] Retry accept() even if accepted connection reports an error - (CVE-2025-48367) - -In case of accept4() returns an error, we should check errno value and decide if we should retry accept4() without waiting next event loop iteration. ---- - src/anet.c | 24 ++++++++++++++++++++++++ - src/anet.h | 1 + - src/cluster.c | 2 ++ - src/socket.c | 2 ++ - src/tls.c | 2 ++ - src/unix.c | 2 ++ - 6 files changed, 33 insertions(+) - -diff --git a/src/anet.c b/src/anet.c -index ad4ac49d89a..d79434cef03 100644 ---- a/src/anet.c -+++ b/src/anet.c -@@ -787,3 +787,27 @@ int anetIsFifo(char *filepath) { - if (stat(filepath, &sb) == -1) return 0; - return S_ISFIFO(sb.st_mode); - } -+ -+/* This function must be called after accept4() fails. It returns 1 if 'err' -+ * indicates accepted connection faced an error, and it's okay to continue -+ * accepting next connection by calling accept4() again. Other errors either -+ * indicate programming errors, e.g. calling accept() on a closed fd or indicate -+ * a resource limit has been reached, e.g. -EMFILE, open fd limit has been -+ * reached. In the latter case, caller might wait until resources are available. -+ * See accept4() documentation for details. */ -+int anetAcceptFailureNeedsRetry(int err) { -+ if (err == ECONNABORTED) -+ return 1; -+ -+#if defined(__linux__) -+ /* For details, see 'Error Handling' section on -+ * https://man7.org/linux/man-pages/man2/accept.2.html */ -+ if (err == ENETDOWN || err == EPROTO || err == ENOPROTOOPT || -+ err == EHOSTDOWN || err == ENONET || err == EHOSTUNREACH || -+ err == EOPNOTSUPP || err == ENETUNREACH) -+ { -+ return 1; -+ } -+#endif -+ return 0; -+} -diff --git a/src/anet.h b/src/anet.h -index 211421940dd..1d3aec9cdf5 100644 ---- a/src/anet.h -+++ b/src/anet.h -@@ -53,5 +53,6 @@ int anetPipe(int fds[2], int read_flags, int write_flags); - int anetSetSockMarkId(char *err, int fd, uint32_t id); - int anetGetError(int fd); - int anetIsFifo(char *filepath); -+int anetAcceptFailureNeedsRetry(int err); - - #endif -diff --git a/src/cluste.c b/src/cluster.c -index 88dc9969190..6f1635e9e5d 100644 ---- a/src/cluster.c -+++ b/src/cluster.c -@@ -1309,6 +1309,8 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) { - while(max--) { - cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport); - if (cfd == ANET_ERR) { -+ if (anetAcceptFailureNeedsRetry(errno)) -+ continue; - if (errno != EWOULDBLOCK) - serverLog(LL_VERBOSE, - "Error accepting cluster node: %s", server.neterr); -diff --git a/src/socket.c b/src/socket.c -index 241a541080d..226b414f85e 100644 ---- a/src/socket.c -+++ b/src/socket.c -@@ -318,6 +318,8 @@ static void connSocketAcceptHandler(aeEventLoop *el, int fd, void *privdata, int - while(max--) { - cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport); - if (cfd == ANET_ERR) { -+ if (anetAcceptFailureNeedsRetry(errno)) -+ continue; - if (errno != EWOULDBLOCK) - serverLog(LL_WARNING, - "Accepting client connection: %s", server.neterr); -diff --git a/src/tls.c b/src/tls.c -index 65526c04f7d..a0733a4b636 100644 ---- a/src/tls.c -+++ b/src/tls.c -@@ -774,6 +774,8 @@ static void tlsAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) - while(max--) { - cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport); - if (cfd == ANET_ERR) { -+ if (anetAcceptFailureNeedsRetry(errno)) -+ continue; - if (errno != EWOULDBLOCK) - serverLog(LL_WARNING, - "Accepting client connection: %s", server.neterr); -diff --git a/src/unix.c b/src/unix.c -index b61cb6d4959..e26f0d27ad1 100644 ---- a/src/unix.c -+++ b/src/unix.c -@@ -100,6 +100,8 @@ static void connUnixAcceptHandler(aeEventLoop *el, int fd, void *privdata, int m - while(max--) { - cfd = anetUnixAccept(server.neterr, fd); - if (cfd == ANET_ERR) { -+ if (anetAcceptFailureNeedsRetry(errno)) -+ continue; - if (errno != EWOULDBLOCK) - serverLog(LL_WARNING, - "Accepting client connection: %s", server.neterr); diff --git a/4-bugfix-for-CVE-2025-32023.patch b/4-bugfix-for-CVE-2025-32023.patch deleted file mode 100644 index 8c379c7c0aa9b21cb3fe459a7b238faecc34ab13..0000000000000000000000000000000000000000 --- a/4-bugfix-for-CVE-2025-32023.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 50188747cbfe43528d2719399a2a3c9599169445 Mon Sep 17 00:00:00 2001 -From: "debing.sun" -Date: Wed, 7 May 2025 18:25:06 +0800 -Subject: [PATCH] Fix out of bounds write in hyperloglog commands - (CVE-2025-32023) - -Co-authored-by: oranagra ---- - src/hyperloglog.c | 47 +++++++++++++++++++++++++++++++---- - tests/unit/hyperloglog.tcl | 51 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 93 insertions(+), 5 deletions(-) - -diff --git a/src/hyperloglog.c b/src/hyperloglog.c -index 2f8c02e2cf2..d6a87822d19 100644 ---- a/src/hyperloglog.c -+++ b/src/hyperloglog.c -@@ -579,6 +579,7 @@ int hllSparseToDense(robj *o) { - struct hllhdr *hdr, *oldhdr = (struct hllhdr*)sparse; - int idx = 0, runlen, regval; - uint8_t *p = (uint8_t*)sparse, *end = p+sdslen(sparse); -+ int valid = 1; - - /* If the representation is already the right one return ASAP. */ - hdr = (struct hllhdr*) sparse; -@@ -598,16 +599,27 @@ int hllSparseToDense(robj *o) { - while(p < end) { - if (HLL_SPARSE_IS_ZERO(p)) { - runlen = HLL_SPARSE_ZERO_LEN(p); -+ if ((runlen + idx) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - idx += runlen; - p++; - } else if (HLL_SPARSE_IS_XZERO(p)) { - runlen = HLL_SPARSE_XZERO_LEN(p); -+ if ((runlen + idx) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - idx += runlen; - p += 2; - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -- if ((runlen + idx) > HLL_REGISTERS) break; /* Overflow. */ -+ if ((runlen + idx) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - while(runlen--) { - HLL_DENSE_SET_REGISTER(hdr->registers,idx,regval); - idx++; -@@ -618,7 +630,7 @@ int hllSparseToDense(robj *o) { - - /* If the sparse representation was valid, we expect to find idx - * set to HLL_REGISTERS. */ -- if (idx != HLL_REGISTERS) { -+ if (!valid || idx != HLL_REGISTERS) { - sdsfree(dense); - return C_ERR; - } -@@ -915,27 +927,40 @@ int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) { - void hllSparseRegHisto(uint8_t *sparse, int sparselen, int *invalid, int* reghisto) { - int idx = 0, runlen, regval; - uint8_t *end = sparse+sparselen, *p = sparse; -+ int valid = 1; - - while(p < end) { - if (HLL_SPARSE_IS_ZERO(p)) { - runlen = HLL_SPARSE_ZERO_LEN(p); -+ if ((runlen + idx) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - idx += runlen; - reghisto[0] += runlen; - p++; - } else if (HLL_SPARSE_IS_XZERO(p)) { - runlen = HLL_SPARSE_XZERO_LEN(p); -+ if ((runlen + idx) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - idx += runlen; - reghisto[0] += runlen; - p += 2; - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -+ if ((runlen + idx) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - idx += runlen; - reghisto[regval] += runlen; - p++; - } - } -- if (idx != HLL_REGISTERS && invalid) *invalid = 1; -+ if ((!valid || idx != HLL_REGISTERS) && invalid) *invalid = 1; - } - - /* ========================= HyperLogLog Count ============================== -@@ -1204,22 +1229,34 @@ int hllMerge(uint8_t *max, robj *hll) { - } else { - uint8_t *p = hll->ptr, *end = p + sdslen(hll->ptr); - long runlen, regval; -+ int valid = 1; - - p += HLL_HDR_SIZE; - i = 0; - while(p < end) { - if (HLL_SPARSE_IS_ZERO(p)) { - runlen = HLL_SPARSE_ZERO_LEN(p); -+ if ((runlen + i) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - i += runlen; - p++; - } else if (HLL_SPARSE_IS_XZERO(p)) { - runlen = HLL_SPARSE_XZERO_LEN(p); -+ if ((runlen + i) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - i += runlen; - p += 2; - } else { - runlen = HLL_SPARSE_VAL_LEN(p); - regval = HLL_SPARSE_VAL_VALUE(p); -- if ((runlen + i) > HLL_REGISTERS) break; /* Overflow. */ -+ if ((runlen + i) > HLL_REGISTERS) { /* Overflow. */ -+ valid = 0; -+ break; -+ } - while(runlen--) { - if (regval > max[i]) max[i] = regval; - i++; -@@ -1227,7 +1264,7 @@ int hllMerge(uint8_t *max, robj *hll) { - p++; - } - } -- if (i != HLL_REGISTERS) return C_ERR; -+ if (!valid || i != HLL_REGISTERS) return C_ERR; - } - return C_OK; - } -diff --git a/tests/unit/hyperloglog.tcl b/tests/unit/hyperloglog.tcl -index f1bbeace9d1..76c0a8d8d2c 100644 ---- a/tests/unit/hyperloglog.tcl -+++ b/tests/unit/hyperloglog.tcl -@@ -137,6 +137,57 @@ start_server {tags {"hll"}} { - set e - } {*WRONGTYPE*} - -+ test {Corrupted sparse HyperLogLogs doesn't cause overflow and out-of-bounds with XZERO opcode} { -+ r del hll -+ -+ # Create a sparse-encoded HyperLogLog header -+ set pl [string cat "HYLL" [binary format c12 {1 0 0 0 0 0 0 0 0 0 0 0}]] -+ -+ # Create an XZERO opcode with the maximum run length of 16384(2^14) -+ set runlen [expr 16384 - 1] -+ set chunk [binary format cc [expr {0b01000000 | ($runlen >> 8)}] [expr {$runlen & 0xff}]] -+ # Fill the HLL with more than 131072(2^17) XZERO opcodes to make the total -+ # run length exceed 4GB, will cause an integer overflow. -+ set repeat [expr 131072 + 1000] -+ for {set i 0} {$i < $repeat} {incr i} { -+ append pl $chunk -+ } -+ -+ # Create a VAL opcode with a value that will cause out-of-bounds. -+ append pl [binary format c 0b11111111] -+ r set hll $pl -+ -+ # This should not overflow and out-of-bounds. -+ assert_error {*INVALIDOBJ*} {r pfcount hll hll} -+ assert_error {*INVALIDOBJ*} {r pfdebug getreg hll} -+ r ping -+ } -+ -+ test {Corrupted sparse HyperLogLogs doesn't cause overflow and out-of-bounds with ZERO opcode} { -+ r del hll -+ -+ # Create a sparse-encoded HyperLogLog header -+ set pl [string cat "HYLL" [binary format c12 {1 0 0 0 0 0 0 0 0 0 0 0}]] -+ -+ # # Create an ZERO opcode with the maximum run length of 64(2^6) -+ set chunk [binary format c [expr {0b00000000 | 0x3f}]] -+ # Fill the HLL with more than 33554432(2^17) ZERO opcodes to make the total -+ # run length exceed 4GB, will cause an integer overflow. -+ set repeat [expr 33554432 + 1000] -+ for {set i 0} {$i < $repeat} {incr i} { -+ append pl $chunk -+ } -+ -+ # Create a VAL opcode with a value that will cause out-of-bounds. -+ append pl [binary format c 0b11111111] -+ r set hll $pl -+ -+ # This should not overflow and out-of-bounds. -+ assert_error {*INVALIDOBJ*} {r pfcount hll hll} -+ assert_error {*INVALIDOBJ*} {r pfdebug getreg hll} -+ r ping -+ } -+ - test {Corrupted dense HyperLogLogs are detected: Wrong length} { - r del hll - r pfadd hll a b c diff --git a/redis-7.2.8.tar.gz b/redis-7.2.10.tar.gz similarity index 32% rename from redis-7.2.8.tar.gz rename to redis-7.2.10.tar.gz index f31257572b14cbc21972adefaf3d393629bbbfe4..d7bf03ae515582ca2cb94edc4afb234b503c95c2 100644 Binary files a/redis-7.2.8.tar.gz and b/redis-7.2.10.tar.gz differ diff --git a/redis.spec b/redis.spec index 91260f5da7b64be5a228412048f26dd760592012..1a0969242dac4bc7cfef5bf670c3ca1a65eba375 100644 --- a/redis.spec +++ b/redis.spec @@ -1,4 +1,4 @@ -%define anolis_release 3 +%define anolis_release 1 # temp workaround to https://bugzilla.redhat.com/2059488 %undefine _package_note_file @@ -11,7 +11,7 @@ %global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) Name: redis -Version: 7.2.8 +Version: 7.2.10 Release: %{anolis_release}%{?dist} Summary: A persistent key-value database # redis, hiredis: BSD-3-Clause @@ -30,8 +30,6 @@ Source10: https://github.com/%{name}/%{name}-doc/archive/%{doc_commit}/ Patch0001: 0001-1st-man-pageis-for-redis-cli-redis-benchmark-redis-c.patch Patch0002: 0002-add-sw_64-support.patch -Patch3: 3-bugfix-for-CVE-2025-48367.patch -Patch4: 4-bugfix-for-CVE-2025-32023.patch BuildRequires: make BuildRequires: gcc @@ -133,11 +131,9 @@ sed -i -e 's|^dir .*$|dir /var/lib/redis|g' redis.conf %ifarch x86_64 sed -e 's/--with-lg-quantum/--with-lg-page=12 --with-lg-quantum/' -i deps/Makefile %endif -%patch -P3 -p1 %ifarch aarch64 sed -e 's/--with-lg-quantum/--with-lg-page=16 --with-lg-quantum/' -i deps/Makefile %endif -%patch -P4 -p1 # Module API version safety check api=`sed -n -e 's/#define REDISMODULE_APIVER_[0-9][0-9]* //p' src/redismodule.h` @@ -292,6 +288,10 @@ fi %changelog +* Fri Aug 29 2025 wenxin - 7.2.10-1 +- Update to 7.2.10 to fix CVE-2025-27151 +- Removed redundant patches included in this version + * Wed Jul 09 2025 tomcruiseqi - 7.2.8-3 - Fix CVE-2025-32023