Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package criu for openSUSE:Factory checked in 
at 2026-07-07 21:05:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/criu (Old)
 and      /work/SRC/openSUSE:Factory/.criu.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "criu"

Tue Jul  7 21:05:22 2026 rev:72 rq:1364243 version:4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/criu/criu.changes        2026-06-10 
17:37:03.358989380 +0200
+++ /work/SRC/openSUSE:Factory/.criu.new.1982/criu.changes      2026-07-07 
21:07:57.976180876 +0200
@@ -1,0 +2,10 @@
+Tue Jul  7 09:20:07 UTC 2026 - Takashi Iwai <[email protected]>
+
+- Backport the fixes from criu-devel branch for the recent 7.x kernels
+  (bsc#1270423):
+  0001-net-Route-veth-restore-through-usernsd-for-userns-mo.patch
+  0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch
+  0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch
+  0004-sockets-Treat-UDPLITE-as-optional-in-collect_err.patch
+
+-------------------------------------------------------------------

New:
----
  0001-net-Route-veth-restore-through-usernsd-for-userns-mo.patch
  0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch
  0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch
  0004-sockets-Treat-UDPLITE-as-optional-in-collect_err.patch

----------(New B)----------
  New:  (bsc#1270423):
  0001-net-Route-veth-restore-through-usernsd-for-userns-mo.patch
  0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch
  New:  0001-net-Route-veth-restore-through-usernsd-for-userns-mo.patch
  0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch
  0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch
  New:  0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch
  0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch
  0004-sockets-Treat-UDPLITE-as-optional-in-collect_err.patch
  New:  0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch
  0004-sockets-Treat-UDPLITE-as-optional-in-collect_err.patch
----------(New E)----------

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

Other differences:
------------------
++++++ criu.spec ++++++
--- /var/tmp/diff_new_pack.HZoBxa/_old  2026-07-07 21:07:58.660204516 +0200
+++ /var/tmp/diff_new_pack.HZoBxa/_new  2026-07-07 21:07:58.676205070 +0200
@@ -44,6 +44,11 @@
 Source0:        
http://github.com/checkpoint-restore/criu/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
 # To be generated; we keep a static one for building without pip
 Source1:        crit.py
+# upstream fixes:
+Patch1:         0001-net-Route-veth-restore-through-usernsd-for-userns-mo.patch
+Patch2:         0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch
+Patch3:         0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch
+Patch4:         0004-sockets-Treat-UDPLITE-as-optional-in-collect_err.patch
 Patch101:       criu-py-install-fix.diff
 Patch102:       0002-Fix-build-with-nftables-installed-in-different-direc.patch
 Patch104:       plugin-dir-path.patch

++++++ 0001-net-Route-veth-restore-through-usernsd-for-userns-mo.patch ++++++
>From 14cb3c201634560fd267aec5bb6217e91aaf46d2 Mon Sep 17 00:00:00 2001
From: Adrian Reber <[email protected]>
Date: Tue, 21 Apr 2026 09:04:51 +0000
Subject: [PATCH] net: Route veth restore through usernsd for userns mode

Starting with Linux kernel commit 7b735ef81286 ("rtnetlink: add
missing netlink_ns_capable() check for peer netns"), creating a
veth pair with a peer in a different network namespace requires
CAP_NET_ADMIN in the peer namespace as well:

    rtnetlink: add missing netlink_ns_capable() check for peer netns

    rtnl_newlink() lacks a CAP_NET_ADMIN capability check on the peer
    network namespace when creating paired devices (veth, vxcan,
    netkit). This allows an unprivileged user with a user namespace
    to create interfaces in arbitrary network namespaces, including
    init_net.

    Add a netlink_ns_capable() check for CAP_NET_ADMIN in the peer
    namespace before allowing device creation to proceed.

Link: 
https://github.com/torvalds/linux/commit/7b735ef81286007794a227ce2539419479c02a5f

When CRIU restores a veth in user namespace mode, it sends the
RTM_NEWLINK request from a netlink socket inside the child user
namespace.  The veth peer is placed into the root network namespace
via IFLA_NET_NS_FD, but the child user namespace does not have
CAP_NET_ADMIN in the root namespace, so the new kernel check
rejects the request with EPERM.

Fix this by routing the veth creation through usernsd when the
peer lives in an external (host) namespace specified via the
--external veth[name] restore option.  usernsd runs with real
root privileges in the init user namespace, so it passes the
capability check in both namespaces.

The usernsd path is only used for external veth mappings, not for
child-to-child namespace veths (has_peer_nsid), because in that
case both namespaces share the same user namespace and already
have CAP_NET_ADMIN in each other.

The approach mirrors restore_one_macvlan(), which already solves
the same CAP_NET_ADMIN-in-both-namespaces problem for macvlan
devices.  A new veth_link_info_userns() builds the RTM_NEWLINK
request without IFLA_NET_NS_FD for the peer -- since usernsd
sends the request from the root network namespace, the peer
naturally stays there.  userns_restore_one_link() then adds a
top-level IFLA_NET_NS_FD to move the main device into the child
namespace.

Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <[email protected]>
---
 criu/net.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/criu/net.c b/criu/net.c
index e5775a32873a..e1dc5973fd14 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1653,6 +1653,94 @@ out:
        return ret;
 }
 
+/*
+ * Simplified veth_link_info for the usernsd path: builds the veth peer
+ * info without adding IFLA_NET_NS_FD for the peer, since the netlink
+ * request will be sent from usernsd's namespace (the root/peer namespace)
+ * and the peer should remain there.
+ */
+static int veth_link_info_userns(struct ns_id *ns, struct net_link *link, 
struct newlink_req *req)
+{
+       NetDeviceEntry *nde = link->nde;
+       struct rtattr *veth_data, *peer_data;
+       struct ifinfomsg ifm;
+       char key[100], *val;
+
+       addattr_l(&req->h, sizeof(*req), IFLA_INFO_KIND, "veth", 4);
+
+       veth_data = NLMSG_TAIL(&req->h);
+       addattr_l(&req->h, sizeof(*req), IFLA_INFO_DATA, NULL, 0);
+       peer_data = NLMSG_TAIL(&req->h);
+       memset(&ifm, 0, sizeof(ifm));
+
+       if (nde->has_peer_nsid)
+               ifm.ifi_index = nde->peer_ifindex;
+       addattr_l(&req->h, sizeof(*req), VETH_INFO_PEER, &ifm, sizeof(ifm));
+
+       /* Set peer name from external mapping if available */
+       snprintf(key, sizeof(key), "veth[%s]", nde->name);
+       val = external_lookup_by_key(key);
+       if (!IS_ERR_OR_NULL(val)) {
+               char *aux = strchrnul(val, '@');
+
+               addattr_l(&req->h, sizeof(*req), IFLA_IFNAME, val, aux - val);
+       }
+
+       /*
+        * No IFLA_NET_NS_FD for the peer -- the request is sent from
+        * usernsd's namespace (the root network namespace) and the
+        * peer stays there.  userns_restore_one_link() adds a top-level
+        * IFLA_NET_NS_FD to move the main device into the child netns.
+        */
+
+       peer_data->rta_len = (char *)NLMSG_TAIL(&req->h) - (char *)peer_data;
+       veth_data->rta_len = (char *)NLMSG_TAIL(&req->h) - (char *)veth_data;
+
+       link->created = true;
+
+       return 0;
+}
+
+/*
+ * When running in user namespaces with a cross-namespace veth peer,
+ * CAP_NET_ADMIN is required in both namespaces for veth creation
+ * (kernel >= 7.0, commit 7b735ef81286). Route the request through
+ * usernsd which runs with real root privileges, similar to
+ * restore_one_macvlan().
+ *
+ * The netlink request is sent from usernsd's namespace (the root
+ * network namespace), so the veth peer stays there. The main device
+ * is moved to the child namespace via a top-level IFLA_NET_NS_FD
+ * added by userns_restore_one_link().
+ */
+static int restore_one_veth_userns(struct ns_id *ns, struct net_link *link)
+{
+       struct newlink_req req;
+       int my_netns, ret;
+
+       my_netns = open_proc(PROC_SELF, "ns/net");
+       if (my_netns < 0)
+               return -1;
+
+       if (populate_newlink_req(ns, &req, RTM_NEWLINK, link,
+                               veth_link_info_userns, NULL) < 0) {
+               close(my_netns);
+               return -1;
+       }
+
+       pr_info("Restoring netdev %s idx %d via usernsd\n",
+               link->nde->name, link->nde->ifindex);
+
+       ret = userns_call(userns_restore_one_link, 0,
+                         &req, sizeof(req), my_netns);
+       if (ret < 0)
+               pr_err("couldn't restore veth interface %s via usernsd\n",
+                      link->nde->name);
+
+       close(my_netns);
+       return ret;
+}
+
 static int sit_link_info(struct ns_id *ns, struct net_link *link, struct 
newlink_req *req)
 {
        NetDeviceEntry *nde = link->nde;
@@ -1762,6 +1850,22 @@ static int __restore_link(struct ns_id *ns, struct 
net_link *link, int nlsk)
                if (!IS_ERR_OR_NULL(val))
                        return move_veth(val, ns, link, nlsk);
 
+               /*
+                * Creating a veth with a cross-namespace peer requires
+                * CAP_NET_ADMIN in both namespaces (kernel >= 7.0).
+                * In user namespace mode, route through usernsd which
+                * has real root when the peer lives in an external
+                * (host) namespace specified via --external veth[name].
+                */
+               if (root_ns_mask & CLONE_NEWUSER) {
+                       char vkey[100];
+
+                       snprintf(vkey, sizeof(vkey), "veth[%s]", nde->name);
+                       val = external_lookup_by_key(vkey);
+                       if (!IS_ERR_OR_NULL(val))
+                               return restore_one_veth_userns(ns, link);
+               }
+
                return restore_one_link(ns, link, nlsk, veth_link_info, NULL);
        case ND_TYPE__TUN:
                return restore_one_tun(ns, link, nlsk);
-- 
2.54.0


++++++ 0002-zdtm-Fix-rseq01-test-for-kernel-7.0-rseq-changes.patch ++++++
>From 5546c06a125dac3c9df2401ae52cebda526c2a27 Mon Sep 17 00:00:00 2001
From: Adrian Reber <[email protected]>
Date: Tue, 21 Apr 2026 09:30:17 +0000
Subject: [PATCH] zdtm: Fix rseq01 test for kernel 7.0 rseq changes

Starting with Linux 7.0, the rseq feature size has grown to 33 bytes
and AT_RSEQ_ALIGN has increased to 64.  This causes sizeof(struct rseq)
from the uapi header to be 64 (33 bytes padded to aligned(32)), while
the actual registration size used by glibc (__rseq_size) is 33.

The rseq01 test was using sizeof(struct rseq) as the registration
size and a test-local __rseq_abi variable (with only 32-byte
alignment from the uapi header) as the rseq area.  Both are
wrong on kernel 7.0:

 - The kernel now checks alignment against __alignof__(struct rseq)
   which is 64 internally; the 32-byte-aligned test variable may
   not satisfy this.

 - sizeof(struct rseq) = 64 does not match the feature size of 33
   that glibc registered with, so re-registration with a different
   size fails.

Fix by:

 - Using __rseq_size (the feature size reported by glibc) as the
   registration size instead of sizeof(struct rseq).

 - Using the glibc-provided rseq area (at thread_pointer() +
   __rseq_offset) which is allocated with proper AT_RSEQ_ALIGN
   alignment, instead of a test-local variable.

Both fall back to the previous behavior when glibc rseq support
is not available.

This mirrors the glibc fix:

    
https://sourceware.org/cgit/glibc/commit/?id=67f303b47dc584f204e3f2441b9832082415eebc

Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <[email protected]>
---
 test/zdtm/transition/rseq01.c | 59 +++++++++++++++++++++++++++++------
 1 file changed, 50 insertions(+), 9 deletions(-)

diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c
index 08a7a8e1a614..9c5925bc450d 100644
--- a/test/zdtm/transition/rseq01.c
+++ b/test/zdtm/transition/rseq01.c
@@ -20,9 +20,19 @@
 #endif
 #endif
 
+/*
+ * HAVE_GLIBC_RSEQ is set when the C library provides rseq support
+ * (__rseq_size, __rseq_offset).  glibc >= 2.35 defines RSEQ_SIG in
+ * <sys/rseq.h>; musl does not, so the test falls back to its own
+ * definitions below.
+ */
+#if defined(RSEQ_SIG)
+#define HAVE_GLIBC_RSEQ 1
+#endif
+
 #if defined(__x86_64__)
 
-#if defined(__x86_64__) && defined(RSEQ_SIG)
+#ifdef HAVE_GLIBC_RSEQ
 static inline void *thread_pointer(void)
 {
        void *result;
@@ -38,11 +48,11 @@ static inline void unregister_old_rseq(void)
                size = 32;
        syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), 
size, 1, RSEQ_SIG);
 }
-#else
+#else /* !HAVE_GLIBC_RSEQ */
 static inline void unregister_old_rseq(void)
 {
 }
-#endif
+#endif /* HAVE_GLIBC_RSEQ */
 
 const char *test_doc = "rseq() transition test";
 const char *test_author = "Alexander Mikhalitsyn 
<[email protected]>";
@@ -97,11 +107,27 @@ static int sys_rseq(volatile struct rseq *rseq_abi, 
uint32_t rseq_len, int flags
        return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
 }
 
+/*
+ * Return the rseq registration size.  Starting with Linux 7.0,
+ * AT_RSEQ_ALIGN is 64 but the feature size is 33, so sizeof(struct rseq)
+ * (padded to alignment) no longer matches the registration size the kernel
+ * expects.  Use __rseq_size when available, clamped to a minimum of 32
+ * for older kernels (mirroring glibc's rseq-internal.h).
+ */
+static uint32_t rseq_reg_size(void)
+{
+#ifdef HAVE_GLIBC_RSEQ
+       if (__rseq_size)
+               return (__rseq_size < 32) ? 32 : __rseq_size;
+#endif
+       return sizeof(struct rseq);
+}
+
 static void register_thread(void)
 {
        int rc;
        unregister_old_rseq();
-       rc = sys_rseq(rseq_ptr, sizeof(struct rseq), 0, RSEQ_SIG);
+       rc = sys_rseq(rseq_ptr, rseq_reg_size(), 0, RSEQ_SIG);
        if (rc) {
                fail("Failed to register rseq");
                exit(1);
@@ -111,7 +137,7 @@ static void register_thread(void)
 static void check_thread(void)
 {
        int rc;
-       rc = sys_rseq(rseq_ptr, sizeof(struct rseq), 0, RSEQ_SIG);
+       rc = sys_rseq(rseq_ptr, rseq_reg_size(), 0, RSEQ_SIG);
        if (!(rc && errno == EBUSY)) {
                fail("Failed to check rseq %d", rc);
                exit(1);
@@ -206,12 +232,27 @@ static intptr_t *cpu_data;
 bool ignore_abort = true;
 int thread_ret;
 
+static volatile struct rseq *rseq_area(void)
+{
+#ifdef HAVE_GLIBC_RSEQ
+       /*
+        * Use the glibc-provided rseq area which is allocated with the
+        * correct alignment (AT_RSEQ_ALIGN, 64 on kernel >= 7.0).
+        * The test-local __rseq_abi only has the uapi header alignment
+        * (32 bytes) which may not satisfy the kernel's requirement.
+        */
+       if (__rseq_size)
+               return (volatile struct rseq *)((char *)thread_pointer() + 
__rseq_offset);
+#endif
+       return &__rseq_abi;
+}
+
 void *thread_routine(void *args)
 {
        int cpu;
 
-       rseq_ptr = &__rseq_abi;
-       memset((void *)rseq_ptr, 0, sizeof(struct rseq));
+       rseq_ptr = rseq_area();
+       memset((void *)rseq_ptr, 0, rseq_reg_size());
        register_thread();
        task_waiter_complete(&waiter, 1);
        task_waiter_wait4(&waiter, 2);
@@ -235,8 +276,8 @@ int main(int argc, char *argv[])
        long nr_cpus;
        pthread_t thread;
 
-       rseq_ptr = &__rseq_abi;
-       memset((void *)rseq_ptr, 0, sizeof(struct rseq));
+       rseq_ptr = rseq_area();
+       memset((void *)rseq_ptr, 0, rseq_reg_size());
 
        test_init(argc, argv);
        nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-- 
2.54.0


++++++ 0003-zdtm-Skip-socket_udplite-test-when-kernel-lacks-UDPL.patch ++++++
>From 9777d2cf091540115998ac711baa90e8f4348751 Mon Sep 17 00:00:00 2001
From: Adrian Reber <[email protected]>
Date: Tue, 21 Apr 2026 07:58:00 +0000
Subject: [PATCH] zdtm: Skip socket_udplite test when kernel lacks UDPLITE

Kernel 7.1 removed IPPROTO_UDPLITE support. Add a checkskip
script that probes for a UDPLITE socket and skips the test
with EPROTONOSUPPORT instead of failing.

Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <[email protected]>
---
 test/zdtm/static/socket_udplite.checkskip | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100755 test/zdtm/static/socket_udplite.checkskip

diff --git a/test/zdtm/static/socket_udplite.checkskip 
b/test/zdtm/static/socket_udplite.checkskip
new file mode 100755
index 000000000000..a562550843f4
--- /dev/null
+++ b/test/zdtm/static/socket_udplite.checkskip
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+# IPPROTO_UDPLITE was removed in kernel 7.1, skip the test if the
+# protocol is not available.
+import socket
+import errno
+
+try:
+       socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 
socket.IPPROTO_UDPLITE).close()
+except OSError as e:
+       if e.errno == errno.EPROTONOSUPPORT:
+               print("UDPLITE is not supported by this kernel.")
+               exit(1)
+       raise
+
+exit(0)
-- 
2.54.0


++++++ 0004-sockets-Treat-UDPLITE-as-optional-in-collect_err.patch ++++++
>From 189ad2c6fea42ae480b10ffe06a28adada10ebc6 Mon Sep 17 00:00:00 2001
From: Adrian Reber <[email protected]>
Date: Mon, 20 Apr 2026 19:19:42 +0000
Subject: [PATCH] sockets: Treat UDPLITE as optional in collect_err()

Kernel 7.1 removed IPPROTO_UDPLITE support. When the UDPLITE diag
module is absent, the netlink request returns -ENOENT, which CRIU
was treating as a fatal error causing the entire dump to fail.

Apply the same treatment as IPPROTO_RAW: return success from the
error callback so the dump can proceed. If a UDPLITE socket is
actually encountered, it will fail at lookup time with a clear
error rather than failing the entire dump preemptively.

Fixes: https://github.com/checkpoint-restore/criu/issues/3002

Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <[email protected]>
---
 criu/sockets.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/criu/sockets.c b/criu/sockets.c
index e4adae03cdd6..7778b4688196 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -827,16 +827,20 @@ static int collect_err(int err, struct ns_id *ns, void 
*arg)
        if (err == -ENOENT) {
                pr_debug("%s: %d\n", msg, err);
                /*
-                * Unlike other modules RAW sockets are
-                * always optional and not commonly used.
+                * Unlike other modules RAW and UDPLITE sockets
+                * are always optional and not commonly used.
                 * Currently we warn user about lack of
                 * a particular module support in "check"
                 * procedure. Thus don't fail on lack of
-                * RAW diags in a regular dump. If we meet
-                * a raw socket we will simply fail on dump
+                * these diags in a regular dump. If we meet
+                * such a socket we will simply fail on dump
                 * procedure because it won't be resolved.
+                *
+                * Note: IPPROTO_UDPLITE support was removed
+                * from the kernel starting with v7.1.
                 */
-               if (gr->protocol == IPPROTO_RAW)
+               if (gr->protocol == IPPROTO_RAW ||
+                   gr->protocol == IPPROTO_UDPLITE)
                        return 0;
                return -ENOENT;
        }
-- 
2.54.0

Reply via email to