From 425e30577f17cc9e0c3fa45807ac54a86d70477d Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 18 May 2026 05:07:08 +0000 Subject: [PATCH 1/5] vxlan: Remove synchronize_net() in vxlan_sock_release(). Initially, a dedicated workqueue was used to defer calling udp_tunnel_sock_release(vxlan_sock->sock) and kfree(vxlan_sock). Later, commit 0412bd931f5f ("vxlan: synchronously and race-free destruction of vxlan sockets") removed the workqueue and instead invoked these two functions immediately after synchronize_net(). This was intended to prevent UAF of the UDP socket in the fast path. ( Note that the "nondeterministic behaviour" mentioned in that commit was not addressed, as another thread not waiting RCU gp still sees the same behaviour. ) However, a week prior to that change, commit ca065d0cf80f ("udp: no longer use SLAB_DESTROY_BY_RCU") had already moved UDP socket freeing to after the RCU grace period. This made the synchronize_net() in vxlan_sock_release() completely redundant. Since vxlan_sock now uses kfree_rcu() and is invoked after udp_tunnel_sock_release(), vxlan_sock is guaranteed to be freed either at the same time or after the UDP socket is released, following the RCU grace period. Let's remove the redundant synchronize_net() in vxlan_sock_release(). Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20260518050726.318824-2-kuniyu@google.com Signed-off-by: Jakub Kicinski --- drivers/net/vxlan/vxlan_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 00facbfabced..8c3885665b58 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -1515,7 +1515,6 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan) #endif RCU_INIT_POINTER(vxlan->vn4_sock, NULL); - synchronize_net(); if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) vxlan_vs_del_vnigrp(vxlan); From 2f7f86db167537bc9c6bb848fc77e4f1089aede2 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 18 May 2026 05:07:09 +0000 Subject: [PATCH 2/5] geneve: Remove synchronize_net() in geneve_sock_release(). vxlan previously had an issue where the fast path could access stale pointers, which was fixed by commit c6fcc4fc5f8b ("vxlan: avoid using stale vxlan socket."). geneve later followed the same pattern, and commit fceb9c3e3825 ("geneve: avoid using stale geneve socket.") copied synchronize_net() from vxlan_sock_release() into geneve_sock_release(). However, that change occurred after commit ca065d0cf80f ("udp: no longer use SLAB_DESTROY_BY_RCU"), and geneve had already been using kfree_rcu() to free geneve_sock. Therefore, the synchronize_net() was never actually needed there. Let's remove the redundant synchronize_net() in geneve_sock_release(). Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20260518050726.318824-3-kuniyu@google.com Signed-off-by: Jakub Kicinski --- drivers/net/geneve.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index b36fad833724..4e5d0a09a82d 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1032,7 +1032,6 @@ static void geneve_sock_release(struct geneve_dev *geneve) #endif rcu_assign_pointer(geneve->sock4, NULL); - synchronize_net(); __geneve_sock_release(gs4); #if IS_ENABLED(CONFIG_IPV6) From 567dbca22b373b05be0aa46eb2e64ee92d4f4790 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 18 May 2026 05:07:10 +0000 Subject: [PATCH 3/5] geneve: Remove synchronize_net() in geneve_unquiesce(). When changing the geneve config, geneve_changelink() sandwiches the config memcpy() between geneve_quiesce() and geneve_unquiesce(). geneve_quiesce() temporarily clears geneve->sock[46] and their sk_user_data, and then calls synchronize_net() to wait for inflight fast paths to finish. geneve_unquiesce() then restores the cleared pointers, but it also superfluously calls synchronize_net(). The latter synchronize_net() provides no benefit; with or without it, inflight fast paths can see either the NULL pointers or the original pointers alongside the new configuration. Let's remove the redundant synchronize_net() in geneve_unquiesce(). Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20260518050726.318824-4-kuniyu@google.com Signed-off-by: Jakub Kicinski --- drivers/net/geneve.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 4e5d0a09a82d..e8ff03ed87dc 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -2206,7 +2206,6 @@ static void geneve_unquiesce(struct geneve_dev *geneve, struct geneve_sock *gs4, if (gs6) rcu_assign_sk_user_data(gs6->sk, gs6); #endif - synchronize_net(); } static int geneve_changelink(struct net_device *dev, struct nlattr *tb[], From d38be9217277ecbfb1bedb28132887229a45c376 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 18 May 2026 05:07:11 +0000 Subject: [PATCH 4/5] bareudp: Remove synchronize_net() in bareudp_sock_release(). synchronize_net() in bareudp_sock_release() has existed since day 1, commit 571912c69f0e ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc."). It was most likely copied from a similar tunneling device like vxlan or geneve. bareudp_sock_release() is called from dev->netdev_ops->ndo_stop(), and synchronize_net() in unregister_netdevice_many_notify() ensures that inflight bareudp fast paths finish before bareudp_dev is freed. Let's remove the redundant synchronize_net() in bareudp_sock_release(). Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20260518050726.318824-5-kuniyu@google.com Signed-off-by: Jakub Kicinski --- drivers/net/bareudp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index 890a0650d9cf..bfcecdcffe67 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -287,7 +287,6 @@ static void bareudp_sock_release(struct bareudp_dev *bareudp) sk = bareudp->sk; rcu_assign_pointer(bareudp->sk, NULL); - synchronize_net(); udp_tunnel_sock_release(sk); } From e6409584dec6d67f5aa9e2e0f55e2c5f0f55d63f Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 18 May 2026 05:07:12 +0000 Subject: [PATCH 5/5] bareudp: Use rtnl_dereference() in bareudp_sock_release(). kernel test robot reported sparse warning in bareudp_sock_release(): drivers/net/bareudp.c:288:12: warning: incorrect type in assignment (different address spaces) drivers/net/bareudp.c:288:12: expected struct sock *sk drivers/net/bareudp.c:288:12: got struct sock [noderef] __rcu *sk The warning is not new and exists since the initial bareudp commit 571912c69f0e ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc."). Let's use rtnl_dereference(). Note that bareudp_sock_release() is called from bareudp_stop() under RTNL, so there is no real issue even without the helper. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202605062359.e3gOfZCr-lkp@intel.com/ Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20260518050726.318824-6-kuniyu@google.com Signed-off-by: Jakub Kicinski --- drivers/net/bareudp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index bfcecdcffe67..5ef841c85526 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -285,7 +285,7 @@ static void bareudp_sock_release(struct bareudp_dev *bareudp) { struct sock *sk; - sk = bareudp->sk; + sk = rtnl_dereference(bareudp->sk); rcu_assign_pointer(bareudp->sk, NULL); udp_tunnel_sock_release(sk); }