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
