Version in base suite: 8.1.1+dfsg1-3+deb13u1 Base version: valkey_8.1.1+dfsg1-3+deb13u1 Target version: valkey_8.1.1+dfsg1-3+deb13u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/v/valkey/valkey_8.1.1+dfsg1-3+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/v/valkey/valkey_8.1.1+dfsg1-3+deb13u2.dsc changelog | 9 ++ patches/CVE-2025-67733.patch | 92 ++++++++++++++++++++++ patches/CVE-2026-21863.patch | 174 +++++++++++++++++++++++++++++++++++++++++++ patches/series | 2 4 files changed, 277 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmppcoidvpf/valkey_8.1.1+dfsg1-3+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmppcoidvpf/valkey_8.1.1+dfsg1-3+deb13u2.dsc: no acceptable signature found diff -Nru valkey-8.1.1+dfsg1/debian/changelog valkey-8.1.1+dfsg1/debian/changelog --- valkey-8.1.1+dfsg1/debian/changelog 2025-10-07 19:33:04.000000000 +0000 +++ valkey-8.1.1+dfsg1/debian/changelog 2026-03-29 08:34:29.000000000 +0000 @@ -1,3 +1,12 @@ +valkey (8.1.1+dfsg1-3+deb13u2) trixie-security; urgency=medium + + * Non-maintainer upload. + * Fix the following vulnerabilities (Closes: #1130911) + - CVE-2025-67733: RESP Protocol Injection via Lua error_reply + - CVE-2026-21863: Remote DoS with malformed Valkey Cluster bus message + + -- Peter Wienemann Sun, 29 Mar 2026 10:34:29 +0200 + valkey (8.1.1+dfsg1-3+deb13u1) trixie-security; urgency=medium * (CVE-2025-49844) A Lua script may lead to remote code execution diff -Nru valkey-8.1.1+dfsg1/debian/patches/CVE-2025-67733.patch valkey-8.1.1+dfsg1/debian/patches/CVE-2025-67733.patch --- valkey-8.1.1+dfsg1/debian/patches/CVE-2025-67733.patch 1970-01-01 00:00:00.000000000 +0000 +++ valkey-8.1.1+dfsg1/debian/patches/CVE-2025-67733.patch 2026-03-29 08:34:29.000000000 +0000 @@ -0,0 +1,92 @@ +Author: Roshan Khatri , Madelyn Olson +Date: Mon, 23 Feb 2026 18:46:43 +0000 +Description: Fix for [CVE-2025-67733] RESP Protocol Injection via Lua error_reply + +Origin: upstream, https://github.com/valkey-io/valkey/commit/3d7598e8c7db4857a0e76582861dec14b555c343.diff +Bug-Debian: https://bugs.debian.org/1130911 +--- + src/lua/script_lua.c | 2 +- + src/networking.c | 14 ++++++++++++++ + src/server.h | 1 + + tests/unit/scripting.tcl | 18 ++++++++++++++++++ + 4 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/src/lua/script_lua.c b/src/lua/script_lua.c +index eb42c5e..4211f93 100644 +--- a/src/lua/script_lua.c ++++ b/src/lua/script_lua.c +@@ -1853,7 +1853,7 @@ void luaCallFunction(scriptRunCtx *run_ctx, + final_msg = + sdscatfmt(final_msg, " script: %s, on %s:%s.", run_ctx->funcname, err_info.source, err_info.line); + } +- addReplyErrorSdsEx(c, final_msg, err_info.ignore_err_stats_update ? ERR_REPLY_FLAG_NO_STATS_UPDATE : 0); ++ addReplyErrorSdsExSafe(c, final_msg, err_info.ignore_err_stats_update ? ERR_REPLY_FLAG_NO_STATS_UPDATE : 0); + luaErrorInformationDiscard(&err_info); + } + lua_pop(lua, 1); /* Consume the Lua error */ +diff --git a/src/networking.c b/src/networking.c +index 0b54308..7c1f25e 100644 +--- a/src/networking.c ++++ b/src/networking.c +@@ -701,6 +701,20 @@ void addReplyError(client *c, const char *err) { + } + + /* Add error reply to the given client. ++ * Supported flags: ++ * ERR_REPLY_FLAG_NO_STATS_UPDATE - indicate not to perform any error stats updates ++ * As a side effect the SDS string is freed. */ ++void addReplyErrorSdsExSafe(client *c, sds err, int flags) { ++ /* Trim any newlines at the end (ones will be added by addReplyErrorLength) */ ++ err = sdstrim(err, "\r\n"); ++ /* Make sure there are no newlines in the middle of the string, otherwise ++ * invalid protocol is emitted. */ ++ err = sdsmapchars(err, "\r\n", " ", 2); ++ addReplyErrorSdsEx(c, err, flags); ++} ++ ++/* Add error reply to the given client. ++ * See addReplyErrorLength for expectations from the input string. + * Supported flags: + * * ERR_REPLY_FLAG_NO_STATS_UPDATE - indicate not to perform any error stats updates */ + void addReplyErrorSdsEx(client *c, sds err, int flags) { +diff --git a/src/server.h b/src/server.h +index 222fd1f..77d895a 100644 +--- a/src/server.h ++++ b/src/server.h +@@ -2692,6 +2692,7 @@ void addReplyOrErrorObject(client *c, robj *reply); + void afterErrorReply(client *c, const char *s, size_t len, int flags); + void addReplyErrorFormatInternal(client *c, int flags, const char *fmt, va_list ap); + void addReplyErrorSdsEx(client *c, sds err, int flags); ++void addReplyErrorSdsExSafe(client *c, sds err, int flags); + void addReplyErrorSds(client *c, sds err); + void addReplyErrorSdsSafe(client *c, sds err); + void addReplyError(client *c, const char *err); +diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl +index e2e59f6..64e0649 100644 +--- a/tests/unit/scripting.tcl ++++ b/tests/unit/scripting.tcl +@@ -2523,6 +2523,24 @@ start_server {tags {"scripting"}} { + assert_equal [errorrstat MY_ERR_CODE r] {} ;# error stats were not incremented + } + ++ test "LUA redis.error_reply API sanitation" { ++ r config resetstat ++ assert_error {ERR*} { ++ r eval {error(redis.error_reply("-ERR\r\n-ERR FAKE"))} 0 ++ } ++ assert_equal PONG [r ping] ++ assert_equal [errorrstat ERR r] {count=1} ++ } ++ ++ test "LUA error function API sanitation" { ++ r config resetstat ++ assert_error {ERR*} { ++ r eval {error("-ERR\r\n-ERR FAKE")} 0 ++ } ++ assert_equal PONG [r ping] ++ assert_equal [errorrstat ERR r] {count=1} ++ } ++ + test "LUA test pcall" { + assert_equal [ + r eval {local status, res = pcall(function() return 1 end); return 'status: ' .. tostring(status) .. ' result: ' .. res} 0 diff -Nru valkey-8.1.1+dfsg1/debian/patches/CVE-2026-21863.patch valkey-8.1.1+dfsg1/debian/patches/CVE-2026-21863.patch --- valkey-8.1.1+dfsg1/debian/patches/CVE-2026-21863.patch 1970-01-01 00:00:00.000000000 +0000 +++ valkey-8.1.1+dfsg1/debian/patches/CVE-2026-21863.patch 2026-03-29 08:34:29.000000000 +0000 @@ -0,0 +1,174 @@ +Author: Roshan Khatri , Madelyn Olson +Date: Mon, 23 Feb 2026 18:46:43 +0000 +Description: Fix for [CVE-2026-21863] Remote DoS with malformed Valkey Cluster bus message + +Origin: backport, https://github.com/valkey-io/valkey/commit/416939303d2550aefff73ac180f41b84c12ba6c0.diff +Bug-Debian: https://bugs.debian.org/1130911 +--- + src/cluster_legacy.c | 21 ++++++++ + tests/unit/cluster/packet.tcl | 113 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 134 insertions(+) + create mode 100644 tests/unit/cluster/packet.tcl + +diff --git a/src/cluster_legacy.c b/src/cluster_legacy.c +index dfb0e7b..eef9cae 100644 +--- a/src/cluster_legacy.c ++++ b/src/cluster_legacy.c +@@ -3132,17 +3132,38 @@ int clusterIsValidPacket(clusterLink *link) { + explen = sizeof(clusterMsg) - sizeof(union clusterMsgData); + explen += (sizeof(clusterMsgDataGossip) * count); + ++ /* Make sure that the number of gossip messages fit in the remaining ++ * space in the message. */ ++ if (totlen < explen) { ++ serverLog(LL_WARNING, ++ "Received invalid %s packet with gossip count %d that exceeds " ++ "total packet length (%lld)", ++ clusterGetMessageTypeString(type), count, (unsigned long long)totlen); ++ return 0; ++ } ++ + /* If there is extension data, which doesn't have a fixed length, + * loop through them and validate the length of it now. */ + if (hdr->mflags[0] & CLUSTERMSG_FLAG0_EXT_DATA) { + clusterMsgPingExt *ext = getInitialPingExt(hdr, count); + while (extensions--) { ++ /* Make sure there is at least enough memory for the extension information so ++ * we can parse it. */ ++ if ((totlen - explen) < sizeof(clusterMsgPingExt)) { ++ serverLog(LL_WARNING, ++ "Received invalid %s packet with extension data that exceeds " ++ "total packet length (%lld)", ++ clusterGetMessageTypeString(type), (unsigned long long)totlen); ++ return 0; ++ } + uint16_t extlen = getPingExtLength(ext); + if (extlen % 8 != 0) { + serverLog(LL_WARNING, "Received a %s packet without proper padding (%d bytes)", + clusterGetMessageTypeString(type), (int)extlen); + return 0; + } ++ /* Similar check to earlier, but we want to make sure the extension length is valid ++ * this time. */ + if ((totlen - explen) < extlen) { + serverLog(LL_WARNING, + "Received invalid %s packet with extension data that exceeds " +diff --git a/tests/unit/cluster/packet.tcl b/tests/unit/cluster/packet.tcl +new file mode 100644 +index 0000000..1b199f0 +--- /dev/null ++++ b/tests/unit/cluster/packet.tcl +@@ -0,0 +1,113 @@ ++# Test that cluster bus messages with certain invalid packets are rejected ++# and don't crash the system. ++proc create_cluster_meet_packet {sender_name sender_port sender_cport} { ++ # Constants ++ set CLUSTER_NAMELEN 40 ++ set CLUSTER_SLOTS 16384 ++ set NET_IP_STR_LEN 46 ++ set CLUSTERMSG_TYPE_MEET 2 ++ ++ # Build the packet ++ set packet "" ++ ++ # Signature "RCmb" (4 bytes) ++ append packet "RCmb" ++ ++ # totlen (uint32_t) - will be updated at the end ++ append packet [binary format I 0] ++ ++ # ver (uint16_t) - protocol version 1 ++ append packet [binary format S 1] ++ ++ # port (uint16_t) ++ append packet [binary format S $sender_port] ++ ++ # type (uint16_t) - MEET ++ append packet [binary format S $CLUSTERMSG_TYPE_MEET] ++ ++ # count (uint16_t) - 100 gossip messages ++ # Value intentionally set to a high value, even though no gossip ++ # messages are included. ++ append packet [binary format S 100] ++ ++ # currentEpoch (uint64_t) ++ append packet [binary format W 1] ++ ++ # configEpoch (uint64_t) ++ append packet [binary format W 1] ++ ++ # offset (uint64_t) ++ append packet [binary format W 0] ++ ++ # sender[40] - node name ++ set sender_padded [string range "${sender_name}[string repeat "\x00" $CLUSTER_NAMELEN]" 0 [expr {$CLUSTER_NAMELEN - 1}]] ++ append packet $sender_padded ++ ++ # myslots[2048] - all zeros ++ append packet [string repeat "\x00" [expr {$CLUSTER_SLOTS / 8}]] ++ ++ # replicaof[40] - all zeros ++ append packet [string repeat "\x00" $CLUSTER_NAMELEN] ++ ++ # myip[46] - all zeros ++ append packet [string repeat "\x00" $NET_IP_STR_LEN] ++ ++ # extensions (uint16_t) - Set to 2 ++ append packet [binary format S 2000000000] ++ ++ # notused1[30] - reserved ++ append packet [string repeat "\x00" 30] ++ ++ # pport (uint16_t) ++ append packet [binary format S 0] ++ ++ # cport (uint16_t) - cluster bus port ++ append packet [binary format S $sender_cport] ++ ++ # flags (uint16_t) - CLUSTER_NODE_PRIMARY ++ append packet [binary format S 1] ++ ++ # state (unsigned char) - CLUSTER_OK ++ append packet [binary format c 0] ++ ++ # mflags[3] - message flags (WITH CLUSTERMSG_FLAG0_EXT_DATA flag set) ++ # CLUSTERMSG_FLAG0_EXT_DATA = (1 << 2) = 4 ++ append packet [binary format ccc 4 0 0] ++ ++ # Update totlen ++ set totlen [string length $packet] ++ set packet [string replace $packet 4 7 [binary format I $totlen]] ++ ++ return $packet ++} ++ ++start_cluster 1 0 {tags {external:skip cluster tls:skip}} { ++ test "Packet with missing gossip messages don't cause invalid read" { ++ set base_port [srv 0 port] ++ set cluster_port [expr {$base_port + 10000}] ++ set fake_node_id "abcdef1234567890abcdef1234567890abcdef12" ++ ++ # Get initial total messages received ++ set info_before [R 0 cluster info] ++ regexp {cluster_stats_messages_received:(\d+)} $info_before -> initial_received ++ ++ # Create a packet with extensions=0 but CLUSTERMSG_FLAG0_EXT_DATA flag set ++ set packet [create_cluster_meet_packet $fake_node_id $base_port $cluster_port] ++ ++ # Verify packet length ++ set packet_len [string length $packet] ++ ++ # Send the packet after configuring the socket to accept binary data ++ set sock [socket 127.0.0.1 $cluster_port] ++ fconfigure $sock -translation binary -encoding binary -buffering none -blocking 1 ++ puts -nonewline $sock $packet ++ flush $sock ++ close $sock ++ ++ wait_for_condition 1000 10 { ++ [CI 0 cluster_stats_messages_received] == 1 ++ } else { ++ fail "Packet was never received" ++ } ++ } ++} diff -Nru valkey-8.1.1+dfsg1/debian/patches/series valkey-8.1.1+dfsg1/debian/patches/series --- valkey-8.1.1+dfsg1/debian/patches/series 2025-10-07 19:32:24.000000000 +0000 +++ valkey-8.1.1+dfsg1/debian/patches/series 2026-03-29 08:34:29.000000000 +0000 @@ -8,3 +8,5 @@ CVE-2025-32023.patch CVE-2025-48367.patch CVE-2025-49844_CVE-2025-46817_CVE-2025-46818_CVE-2025-46819.patch +CVE-2025-67733.patch +CVE-2026-21863.patch