Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package valkey for openSUSE:Factory checked 
in at 2025-07-18 15:57:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/valkey (Old)
 and      /work/SRC/openSUSE:Factory/.valkey.new.8875 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "valkey"

Fri Jul 18 15:57:44 2025 rev:14 rq:1294199 version:8.1.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/valkey/valkey.changes    2025-06-13 
18:42:25.715460982 +0200
+++ /work/SRC/openSUSE:Factory/.valkey.new.8875/valkey.changes  2025-07-18 
15:58:31.478456963 +0200
@@ -1,0 +2,11 @@
+Tue Jul 15 21:47:08 UTC 2025 - Antonio Teixeira <antonio.teixe...@suse.com>
+
+- Update to 8.1.3:
+  - Security fixes
+    * CVE-2025-32023 prevent out-of-bounds write during hyperloglog operations
+      (boo#1246059)
+    * CVE-2025-48367 retry accept on transient errors (#2315) (boo#1246058)
+  - Bug fixes
+    * Fix missing response when AUTH is errored inside a transaction (#2287)
+
+-------------------------------------------------------------------

Old:
----
  valkey-8.1.2.tar.gz

New:
----
  valkey-8.1.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ valkey.spec ++++++
--- /var/tmp/diff_new_pack.xQJkTY/_old  2025-07-18 15:58:32.054481026 +0200
+++ /var/tmp/diff_new_pack.xQJkTY/_new  2025-07-18 15:58:32.058481193 +0200
@@ -26,7 +26,7 @@
 %global make_flags CFLAGS="%{build_cflags}" DEBUG="" V="echo" 
PREFIX=%{buildroot}%{_prefix} BUILD_WITH_SYSTEMD=yes BUILD_TLS=yes
 
 Name:           valkey
-Version:        8.1.2
+Version:        8.1.3
 Release:        0
 Summary:        Persistent key-value database
 License:        BSD-3-Clause

++++++ valkey-8.1.2.tar.gz -> valkey-8.1.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/00-RELEASENOTES 
new/valkey-8.1.3/00-RELEASENOTES
--- old/valkey-8.1.2/00-RELEASENOTES    2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/00-RELEASENOTES    2025-07-07 09:18:20.000000000 +0200
@@ -10,6 +10,22 @@
 
--------------------------------------------------------------------------------
 
 
================================================================================
+Valkey 8.1.3  -  Released Sun 07 July 2025
+================================================================================
+
+Upgrade urgency SECURITY: This release includes security fixes we recommend you
+apply as soon as possible.
+
+Bug fixes
+=========
+* Fix missing response when AUTH is errored inside a transaction (#2287)
+
+Security fixes
+==============
+* CVE-2025-32023 prevent out-of-bounds write during hyperloglog operations 
(#2146)
+* CVE-2025-48367 retry accept on transient errors (#2315)
+
+================================================================================
 Valkey 8.1.2  -  Released Wed 11 June 2025
 
================================================================================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/acl.c new/valkey-8.1.3/src/acl.c
--- old/valkey-8.1.2/src/acl.c  2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/acl.c  2025-07-07 09:18:20.000000000 +0200
@@ -1439,7 +1439,12 @@
 /* If `err` is provided, this is added as an error reply to the client.
  * Otherwise, the standard Auth error is added as a reply. */
 void addAuthErrReply(client *c, robj *err) {
-    if (clientHasPendingReplies(c)) return;
+    /* Note that a module auth can add reply in its callback, or not
+     * add reply and just return an error robj in its callback. So in
+     * here, we use buffered_reply flag to determine if auth command
+     * has already had a reply added. */
+    if (c->flag.buffered_reply) return;
+
     if (!err) {
         addReplyError(c, "-WRONGPASS invalid username-password pair or user is 
disabled.");
         return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/anet.c new/valkey-8.1.3/src/anet.c
--- old/valkey-8.1.2/src/anet.c 2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/anet.c 2025-07-07 09:18:20.000000000 +0200
@@ -639,6 +639,37 @@
     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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/anet.h new/valkey-8.1.3/src/anet.h
--- old/valkey-8.1.2/src/anet.h 2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/anet.h 2025-07-07 09:18:20.000000000 +0200
@@ -74,5 +74,6 @@
 int anetSetSockMarkId(char *err, int fd, uint32_t id);
 int anetGetError(int fd);
 int anetIsFifo(char *filepath);
+int anetRetryAcceptOnError(int err);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/cluster_legacy.c 
new/valkey-8.1.3/src/cluster_legacy.c
--- old/valkey-8.1.2/src/cluster_legacy.c       2025-06-11 22:15:00.000000000 
+0200
+++ new/valkey-8.1.3/src/cluster_legacy.c       2025-07-07 09:18:20.000000000 
+0200
@@ -1504,6 +1504,7 @@
     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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/hyperloglog.c 
new/valkey-8.1.3/src/hyperloglog.c
--- old/valkey-8.1.2/src/hyperloglog.c  2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/hyperloglog.c  2025-07-07 09:18:20.000000000 +0200
@@ -602,6 +602,7 @@
     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;
@@ -621,16 +622,27 @@
     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++;
@@ -641,7 +653,7 @@
 
     /* 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;
     }
@@ -938,27 +950,40 @@
 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 ==============================
@@ -1230,22 +1255,34 @@
     } 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++;
@@ -1253,7 +1290,7 @@
                 p++;
             }
         }
-        if (i != HLL_REGISTERS) return C_ERR;
+        if (!valid || i != HLL_REGISTERS) return C_ERR;
     }
     return C_OK;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/socket.c 
new/valkey-8.1.3/src/socket.c
--- old/valkey-8.1.2/src/socket.c       2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/socket.c       2025-07-07 09:18:20.000000000 +0200
@@ -322,6 +322,7 @@
     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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/tls.c new/valkey-8.1.3/src/tls.c
--- old/valkey-8.1.2/src/tls.c  2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/tls.c  2025-07-07 09:18:20.000000000 +0200
@@ -788,6 +788,7 @@
     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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/unix.c new/valkey-8.1.3/src/unix.c
--- old/valkey-8.1.2/src/unix.c 2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/unix.c 2025-07-07 09:18:20.000000000 +0200
@@ -107,6 +107,7 @@
     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;
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/src/version.h 
new/valkey-8.1.3/src/version.h
--- old/valkey-8.1.2/src/version.h      2025-06-11 22:15:00.000000000 +0200
+++ new/valkey-8.1.3/src/version.h      2025-07-07 09:18:20.000000000 +0200
@@ -4,8 +4,8 @@
  * similar. */
 #define SERVER_NAME "valkey"
 #define SERVER_TITLE "Valkey"
-#define VALKEY_VERSION "8.1.2"
-#define VALKEY_VERSION_NUM 0x00080102
+#define VALKEY_VERSION "8.1.3"
+#define VALKEY_VERSION_NUM 0x00080103
 /* The release stage is used in order to provide release status information.
  * In unstable branch the status is always "dev".
  * During release process the status will be set to rc1,rc2...rcN.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/tests/unit/hyperloglog.tcl 
new/valkey-8.1.3/tests/unit/hyperloglog.tcl
--- old/valkey-8.1.2/tests/unit/hyperloglog.tcl 2025-06-11 22:15:00.000000000 
+0200
+++ new/valkey-8.1.3/tests/unit/hyperloglog.tcl 2025-07-07 09:18:20.000000000 
+0200
@@ -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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/valkey-8.1.2/tests/unit/multi.tcl 
new/valkey-8.1.3/tests/unit/multi.tcl
--- old/valkey-8.1.2/tests/unit/multi.tcl       2025-06-11 22:15:00.000000000 
+0200
+++ new/valkey-8.1.3/tests/unit/multi.tcl       2025-07-07 09:18:20.000000000 
+0200
@@ -901,6 +901,13 @@
         r flushall
         r ping
      }
+
+    test "AUTH errored inside MULTI will add the reply" {
+        r config set requirepass ""
+        r multi
+        r auth no-user foobar
+        assert_error {WRONGPASS invalid username-password pair or user is 
disabled.} {r exec}
+    }
 }
 
 start_server {overrides {appendonly {yes} appendfilename {appendonly.aof} 
appendfsync always} tags {external:skip}} {

Reply via email to