Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libnfs for openSUSE:Factory checked 
in at 2026-11-03 17:51:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libnfs (Old)
 and      /work/SRC/openSUSE:Factory/.libnfs.new.1257 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libnfs"

Tue Nov  3 17:51:27 2026 rev:14 rq:1394338 version:6.0.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/libnfs/libnfs.changes    2026-07-10 
17:39:05.676617580 +0200
+++ /work/SRC/openSUSE:Factory/.libnfs.new.1257/libnfs.changes  2026-11-03 
17:51:31.202174938 +0100
@@ -1,0 +2,6 @@
+Thu Oct 29 03:14:16 UTC 2026 - Xiaoguang Wang <[email protected]>
+
+- Add libnfs-CVE-2026-108985.patch: ZDR: enforce the maxsize bound
+  (bsc#1284986, CVE-2026-108985).
+
+-------------------------------------------------------------------

New:
----
  libnfs-CVE-2026-108985.patch

----------(New B)----------
  New:
- Add libnfs-CVE-2026-108985.patch: ZDR: enforce the maxsize bound
  (bsc#1284986, CVE-2026-108985).
----------(New E)----------

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

Other differences:
------------------
++++++ libnfs.spec ++++++
--- /var/tmp/diff_new_pack.qdg62S/_old  2026-11-03 17:51:32.573232247 +0100
+++ /var/tmp/diff_new_pack.qdg62S/_new  2026-11-03 17:51:32.576232372 +0100
@@ -32,6 +32,8 @@
 Patch1:         libnfs-CVE-2026-53689.patch
 # PATCH-FIX-UPSTReAM libnfs-CVE-2026-57918.patch [email protected] -- socket: 
prevent an underflow in xid.
 Patch2:         libnfs-CVE-2026-57918.patch
+# PATCH-FIX-UPSTREAM libnfs-CVE-2026-108985.patch bsc#1284986 [email protected] 
-- ZDR: enforce the maxsize bound
+Patch3:         libnfs-CVE-2026-108985.patch
 BuildRequires:  autoconf
 BuildRequires:  libtool
 BuildRequires:  pkgconfig

++++++ libnfs-CVE-2026-108985.patch ++++++
>From f7c4c8b65e9e2373a43c31c09aaff60b809c493d Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <[email protected]>
Date: Thu, 8 Oct 2026 07:22:11 +1000
Subject: [PATCH] ZDR: enforce the maxsize bound

libnfs_zdr_bytes(), libnfs_zdr_string() and libnfs_zdr_array() took a
maxsize and never consulted it. A decode into a caller-supplied buffer
copied the wire length with memcpy(), so a preallocated destination
could be written past its end. Limits supplied by the generated
decoders, including NFS4_FHSIZE and NFS4_OPAQUE_LIMIT, were skipped
the same way.

A positive maxsize is now a hard limit, checked before any copy or
allocation. Zero and ~0 stay unlimited: rpcgen emits ~0 where the
protocol states no limit, and the AUTH credential and verifier paths
pass the live length, which is zero on a zeroed object. A
caller-supplied byte buffer remains maxsize bytes long, so a zero
maxsize accepts only an empty copy into that buffer.

Jinpyo Lee, Tobabz Team, reported that the bound was never enforced.

Reported-by: Jinpyo Lee <[email protected]>
Signed-off-by: Ronnie Sahlberg <[email protected]>

Backport of 7613236 to 5.0.3 on top of 55c18ea. Test files omitted.
---
 lib/libnfs-zdr.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/lib/libnfs-zdr.c b/lib/libnfs-zdr.c
index a259de1..3070767 100644
--- a/lib/libnfs-zdr.c
+++ b/lib/libnfs-zdr.c
@@ -167,15 +167,37 @@ bool_t libnfs_zdr_int64_t(ZDR *zdrs, int64_t *i)
        return libnfs_zdr_uint64_t(zdrs, (uint64_t *)i);
 }
 
+/*
+ * Positive maxsize values are hard limits. ~0 is what rpcgen emits when
+ * the protocol states no limit. Zero is unlimited too: the AUTH
+ * credential and verifier paths pass the live length, and a zeroed
+ * object still has length zero.
+ */
+static bool_t libnfs_zdr_size_ok(uint32_t size, uint32_t maxsize)
+{
+        if (maxsize == 0 || maxsize == ~(uint32_t)0) {
+                return TRUE;
+        }
+        return size <= maxsize;
+}
+
 bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t 
maxsize)
 {
         uint32_t zero = 0;
         int pad;
 
+        if (zdrs->x_op == ZDR_ENCODE && !libnfs_zdr_size_ok(*size, maxsize)) {
+                return FALSE;
+        }
+
        if (!libnfs_zdr_u_int(zdrs, size)) {
                return FALSE;
        }
 
+        if (zdrs->x_op == ZDR_DECODE && !libnfs_zdr_size_ok(*size, maxsize)) {
+                return FALSE;
+        }
+
        if (zdrs->pos + (int)*size > zdrs->size) {
                return FALSE;
        }
@@ -194,6 +216,14 @@ bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t 
*size, uint32_t maxsize
                return TRUE;
        case ZDR_DECODE:
                if (*bufp != NULL) {
+                        /*
+                         * Caller-supplied storage is maxsize bytes long.
+                         * A zero maxsize leaves that storage empty, so
+                         * only an empty field may be copied into it.
+                         */
+                        if (*size > maxsize) {
+                                return FALSE;
+                        }
                        memcpy(*bufp, &zdrs->buf[zdrs->pos], *size);
                } else {
                        *bufp = &zdrs->buf[zdrs->pos];
@@ -279,6 +309,9 @@ bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t 
maxsize)
 
        if (zdrs->x_op == ZDR_ENCODE) {
                size = strlen(*strp);
+                if (!libnfs_zdr_size_ok(size, maxsize)) {
+                        return FALSE;
+                }
        }
 
        if (!libnfs_zdr_u_int(zdrs, &size)) {
@@ -287,6 +320,9 @@ bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t 
maxsize)
        if (size > zdrs->size) {
                return FALSE;
        }
+        if (zdrs->x_op == ZDR_DECODE && !libnfs_zdr_size_ok(size, maxsize)) {
+                return FALSE;
+        }
        if (zdrs->pos + (int)size > zdrs->size) {
                return FALSE;
        }
@@ -325,10 +361,18 @@ bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t 
*size, uint32_t maxsize
        int  i;
         uint32_t s;
 
+        if (zdrs->x_op == ZDR_ENCODE && !libnfs_zdr_size_ok(*size, maxsize)) {
+                return FALSE;
+        }
+
        if (!libnfs_zdr_u_int(zdrs, size)) {
                return FALSE;
        }
 
+        if (zdrs->x_op == ZDR_DECODE && !libnfs_zdr_size_ok(*size, maxsize)) {
+                return FALSE;
+        }
+
         if (*size > UINT32_MAX/elsize) {
                 return FALSE;
         }
-- 
2.54.0

Reply via email to