1
0
Fork 0
mirror of https://gitlab.alpinelinux.org/alpine/aports.git synced 2025-07-12 18:59:50 +03:00

main/valkey: patch CVE-2025-32023 & CVE-2025-48367

This commit is contained in:
fossdd 2025-07-07 00:32:16 +02:00 committed by achill (fossdd)
parent db64a7a0c8
commit 717c26d65a
3 changed files with 313 additions and 1 deletions

View file

@ -4,7 +4,7 @@
# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
pkgname=valkey
pkgver=8.1.1
pkgrel=1
pkgrel=2
pkgdesc="Open source high-performance key/value datastore (fork of Redis)"
url="https://valkey.io/"
arch="all"
@ -32,9 +32,14 @@ source="https://github.com/valkey-io/valkey/archive/$pkgver/valkey-$pkgver.tar.g
$pkgname-sentinel.initd
$pkgname-sentinel.confd
CVE-2025-27151.patch
CVE-2025-32023.patch
CVE-2025-48367.patch
"
# secfixes:
# 8.1.1-r2:
# - CVE-2025-32023
# - CVE-2025-48367
# 8.1.1-r1:
# - CVE-2025-27151
# 7.2.9-r0:
@ -114,4 +119,6 @@ d0311d2bfade7efbfa2bdcc6c74e8e8a151c09c627e30f5cea1826155dcb4f7ca4c1d35aba26bcce
dd407cb4047524114b4814a28993978acbe300989acc466ec3809171bf19a1e0562756f7b5954981a087a37437c2c281e4a3667d361cfa8873d1c20d1b900632 valkey-sentinel.initd
926316561f0802b577caee03e7bccc5538dc8270095df95853549fdd519fac8d0e89bc3e563cdba2d7ec0dfe10db5e50b95859549597beec894c820abfdbecee valkey-sentinel.confd
bc769dd0b5b30e657e176ddde4836ac1781a9cf9caccf19d635bf223ac58889aa5f7335b11f542f9240ab177f7c221651394584255eb4857b780e8a1d3ce45ea CVE-2025-27151.patch
c5d9be725aaaa0e49590d91a7c6ad55d409cf75a981ce017f411627c5c79fda1812fa0f4de522842aaef26f9cf75d33fb3afe652354c36e3e41a86a06d67e575 CVE-2025-32023.patch
e990ed04b6ba14f92335cf559f759e7f52bae51e037f3df2275408d5d4c10b5a18cc18aba8ea1939f28007a9a9ac2f3063b98eaf4d92c4959d7c5d8a836eb15e CVE-2025-48367.patch
"

View file

@ -0,0 +1,186 @@
Patch-Source: https://github.com/valkey-io/valkey/commit/20f5199d96baf0c64bd4e7d042b6274c4e773bcb
---
From 20f5199d96baf0c64bd4e7d042b6274c4e773bcb Mon Sep 17 00:00:00 2001
From: Ran Shidlansik <ranshid@amazon.com>
Date: Sun, 6 Jul 2025 23:20:32 +0300
Subject: [PATCH] Apply fixed for CVE-2025-32023 (#2314)
Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
Co-authored-by: Madelyn Olson <madelyneolson@gmail.com>
---
src/hyperloglog.c | 47 ++++++++++++++++++++++++++++++++++----
tests/unit/hyperloglog.tcl | 26 +++++++++++++++++++++
2 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/src/hyperloglog.c b/src/hyperloglog.c
index 910e3ef6bb..28c0153dc3 100644
--- a/src/hyperloglog.c
+++ b/src/hyperloglog.c
@@ -619,6 +619,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;
@@ -638,16 +639,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++;
@@ -658,7 +670,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;
}
@@ -955,27 +967,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 ==============================
@@ -1344,22 +1369,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++;
@@ -1367,7 +1404,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 765d5e0bdd..ca46a407bd 100644
--- a/tests/unit/hyperloglog.tcl
+++ b/tests/unit/hyperloglog.tcl
@@ -1,4 +1,30 @@
start_server {tags {"hll"}} {
+ test {CVE-2025-32023: Sparse HLL XZERO overflow triggers crash} {
+ # Build a valid HLL header for sparse encoding
+ set hll [binary format cccc 72 89 76 76] ; # "HYLL"
+ append hll [binary format cccc 1 0 0 0] ; # encoding=sparse, 3 reserved
+ append hll [binary format cccccccc 0 0 0 0 0 0 0 0] ; # cached cardinality
+
+ # We need alternating XZERO and ZERO opcodes to build up a large enough
+ # HyperLogLog value that will overflow the runlength.
+ # 0x7f 0xff is the XZERO opcode that sets the index to 16384.
+ # 0x3f is the ZERO opcode that sets the index to 256.
+ # We repeat this pattern at least 33554432 times to overflow the runlength,
+ # 50331648 is just 33554432 * 1.5, which is just a round number.
+ append hll [string repeat [binary format ccc 0x7f 0xff 0x3f] 50331648]
+
+ # We need an actual value at the end to trigger the out of bounds write
+ append hll [binary format c 0x80]
+
+ # Set the raw value into the key
+ r set hll_overflow $hll
+ r pfadd hll_merge_source hi
+
+ # Test pfadd and pfmerge, these used to crash but now error
+ assert_error {*INVALIDOBJ*} {r pfmerge fail_target hll_overflow hll_merge_source}
+ assert_error {*INVALIDOBJ*} {r pfadd hll_overflow foo}
+ } {} {large-memory}
+
test {HyperLogLog self test passes} {
catch {r pfselftest} e
set e

View file

@ -0,0 +1,119 @@
Patch-Source: https://github.com/valkey-io/valkey/commit/cb10d9d78f35945b667e46967b3980e89954d73b
---
From cb10d9d78f35945b667e46967b3980e89954d73b Mon Sep 17 00:00:00 2001
From: Ran Shidlansik <ranshid@amazon.com>
Date: Mon, 7 Jul 2025 00:40:08 +0300
Subject: [PATCH] retry accept on transient errors (CVE-2025-48367) (#2315)
Signed-off-by: Ran Shidlansik <ranshid@amazon.com>
---
src/anet.c | 31 +++++++++++++++++++++++++++++++
src/anet.h | 1 +
src/cluster_legacy.c | 1 +
src/socket.c | 1 +
src/tls.c | 1 +
src/unix.c | 1 +
6 files changed, 36 insertions(+)
diff --git a/src/anet.c b/src/anet.c
index 5e970e2cf2..8bc1626966 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -659,6 +659,37 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog, char *group)
return s;
}
+/* For some error cases indicates transient errors and accept can be retried
+ * in order to serve other pending connections. This function should be called with the last errno,
+ * right after anetTcpaccept or anetUnixAccept returned an error in order to retry them. */
+int anetRetryAcceptOnError(int err) {
+ /* This is a transient error which can happen, for example, when
+ * a client initiates a TCP handshake (SYN),
+ * the server receives and queues it in the pending connections queue (the SYN queue),
+ * but before accept() is called, the connection is aborted.
+ * in such cases we can continue accepting other connections. ß*/
+ if (err == ECONNABORTED)
+ return 1;
+
+#if defined(__linux__)
+ /* https://www.man7.org/linux/man-pages/man2/accept4.2 suggests that:
+ * Linux accept() (and accept4()) passes already-pending network
+ errors on the new socket as an error code from accept(). This
+ behavior differs from other BSD socket implementations. For
+ reliable operation the application should detect the network
+ errors defined for the protocol after accept() and treat them like
+ EAGAIN by retrying. In the case of TCP/IP, these are ENETDOWN,
+ EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP,
+ and ENETUNREACH. */
+ if (err == ENETDOWN || err == EPROTO || err == ENOPROTOOPT ||
+ err == EHOSTDOWN || err == ENONET || err == EHOSTUNREACH ||
+ err == EOPNOTSUPP || err == ENETUNREACH) {
+ return 1;
+ }
+#endif
+ return 0;
+}
+
/* Accept a connection and also make sure the socket is non-blocking, and CLOEXEC.
* returns the new socket FD, or -1 on error. */
static int anetGenericAccept(char *err, int s, struct sockaddr *sa, socklen_t *len) {
diff --git a/src/anet.h b/src/anet.h
index f5bca1acab..79a4ecebfb 100644
--- a/src/anet.h
+++ b/src/anet.h
@@ -74,6 +74,7 @@ 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 anetRetryAcceptOnError(int err);
static inline int anetHasMptcp(void) {
#ifdef IPPROTO_MPTCP
diff --git a/src/cluster_legacy.c b/src/cluster_legacy.c
index 82a2fad21b..236f58639e 100644
--- a/src/cluster_legacy.c
+++ b/src/cluster_legacy.c
@@ -1585,6 +1585,7 @@ 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 (anetRetryAcceptOnError(errno)) continue;
if (errno != EWOULDBLOCK) serverLog(LL_VERBOSE, "Error accepting cluster node: %s", server.neterr);
return;
}
diff --git a/src/socket.c b/src/socket.c
index fba18f2161..5a1ca11f75 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -323,6 +323,7 @@ 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 (anetRetryAcceptOnError(errno)) continue;
if (errno != EWOULDBLOCK) serverLog(LL_WARNING, "Accepting client connection: %s", server.neterr);
return;
}
diff --git a/src/tls.c b/src/tls.c
index e5af01b2fa..5360212b63 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -791,6 +791,7 @@ 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 (anetRetryAcceptOnError(errno)) continue;
if (errno != EWOULDBLOCK) serverLog(LL_WARNING, "Accepting client connection: %s", server.neterr);
return;
}
diff --git a/src/unix.c b/src/unix.c
index 58a07e50a4..bc45e45193 100644
--- a/src/unix.c
+++ b/src/unix.c
@@ -118,6 +118,7 @@ static void connUnixAcceptHandler(aeEventLoop *el, int fd, void *privdata, int m
while (max--) {
cfd = anetUnixAccept(server.neterr, fd);
if (cfd == ANET_ERR) {
+ if (anetRetryAcceptOnError(errno)) continue;
if (errno != EWOULDBLOCK) serverLog(LL_WARNING, "Accepting client connection: %s", server.neterr);
return;
}