From 72d248ce260da8195ab8a8e2233aaabcd62be00a Mon Sep 17 00:00:00 2001 From: fandeyuan Date: Tue, 26 Aug 2025 15:05:37 +0800 Subject: [PATCH] fix-CVE-2025-48367 --- ...accepted-connection-reports-an-error.patch | 107 ++++++++++++++++++ redis6.spec | 12 +- 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 Retry-accept-even-if-accepted-connection-reports-an-error.patch diff --git a/Retry-accept-even-if-accepted-connection-reports-an-error.patch b/Retry-accept-even-if-accepted-connection-reports-an-error.patch new file mode 100644 index 0000000..bf6d235 --- /dev/null +++ b/Retry-accept-even-if-accepted-connection-reports-an-error.patch @@ -0,0 +1,107 @@ +From 7d8a7a56ba63aa362c9fe0eace19f5f3d113aabf 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 | 2 +- + src/cluster.c | 2 ++ + src/networking.c | 6 ++++++ + 4 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/src/anet.c b/src/anet.c +index a121c27..7f17ebf 100644 +--- a/src/anet.c ++++ b/src/anet.c +@@ -593,3 +593,27 @@ int anetFormatFdAddr(int fd, char *buf, size_t buf_len, int fd_to_str_type) { + anetFdToString(fd,ip,sizeof(ip),&port,fd_to_str_type); + return anetFormatAddr(buf, buf_len, ip, port); + } ++ ++/* 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 2a685cc..adedaf3 100644 +--- a/src/anet.h ++++ b/src/anet.h +@@ -72,5 +72,5 @@ int anetFdToString(int fd, char *ip, size_t ip_len, int *port, int fd_to_str_typ + int anetKeepAlive(char *err, int fd, int interval); + int anetFormatAddr(char *fmt, size_t fmt_len, char *ip, int port); + int anetFormatFdAddr(int fd, char *buf, size_t buf_len, int fd_to_str_type); +- ++int anetAcceptFailureNeedsRetry(int err); + #endif +diff --git a/src/cluster.c b/src/cluster.c +index 88626d9..8de3aa5 100644 +--- a/src/cluster.c ++++ b/src/cluster.c +@@ -690,6 +690,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/networking.c b/src/networking.c +index fe454ef..c44d82f 100644 +--- a/src/networking.c ++++ b/src/networking.c +@@ -1187,6 +1187,8 @@ void acceptTcpHandler(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); +@@ -1208,6 +1210,8 @@ void acceptTLSHandler(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); +@@ -1228,6 +1232,8 @@ void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) { + 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); +-- +2.43.0 + diff --git a/redis6.spec b/redis6.spec index 1790ac8..f189833 100644 --- a/redis6.spec +++ b/redis6.spec @@ -6,7 +6,7 @@ %global Pname redis Name: redis6 Version: 6.2.7 -Release: 2 +Release: 3 Summary: A persistent key-value database License: BSD and MIT URL: https://redis.io @@ -20,8 +20,9 @@ Source9: macros.%{Pname} Source10: https://github.com/%{Pname}/%{Pname}-doc/archive/%{doc_commit}/%{Pname}-doc-%{short_doc_commit}.tar.gz Patch0001: Modify-aarch64-architecture-jemalloc-page-size-from-from-4k-to-64k.patch - Patch0002: fix-help-info.patch +Patch0003: Retry-accept-even-if-accepted-connection-reports-an-error.patch + BuildRequires: make gcc %if %{with tests} BuildRequires: procps-ng tcl @@ -80,10 +81,14 @@ administration and development. %prep tar -xvf %{SOURCE10} %setup -n %{Pname}-%{version} + %ifarch aarch64 %patch0001 -p1 %patch0002 -p1 %endif + +%patch0003 -p1 + mv ../%{Pname}-doc-%{doc_commit} doc mv deps/lua/COPYRIGHT COPYRIGHT-lua mv deps/jemalloc/COPYING COPYING-jemalloc @@ -212,6 +217,9 @@ fi %{_docdir}/%{Pname} %changelog +* Tue Aug 26 2025 Deyuan Fan - 6.2.7-3 +- Retry accept() even if accepted connection reports an error (CVE-2025-48367) + * Wed Dec 20 2023 xiexing - 6.2.7-2 - add Conflicts with redis and redis5 -- Gitee