public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Steffen Klassert <steffen.klassert@secunet.com>
To: David Miller <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
	Steffen Klassert <steffen.klassert@secunet.com>,
	<netdev@vger.kernel.org>
Subject: [PATCH 16/20] xfrm: avoid RCU warnings around the per-netns netlink socket
Date: Mon, 23 Mar 2026 09:33:57 +0100	[thread overview]
Message-ID: <20260323083440.2741292-17-steffen.klassert@secunet.com> (raw)
In-Reply-To: <20260323083440.2741292-1-steffen.klassert@secunet.com>

From: Sabrina Dubroca <sd@queasysnail.net>

net->xfrm.nlsk is used in 2 types of contexts:
 - fully under RCU, with rcu_read_lock + rcu_dereference and a NULL check
 - in the netlink handlers, with requests coming from a userspace socket

In the 2nd case, net->xfrm.nlsk is guaranteed to stay non-NULL and the
object is alive, since we can't enter the netns destruction path while
the user socket holds a reference on the netns.

After adding the __rcu annotation to netns_xfrm.nlsk (which silences
sparse warnings in the RCU users and __net_init code), we need to tell
sparse that the 2nd case is safe. Add a helper for that.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/net/netns/xfrm.h |  2 +-
 net/xfrm/xfrm_user.c     | 25 +++++++++++++++++--------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 23dd647fe024..b73983a17e08 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -59,7 +59,7 @@ struct netns_xfrm {
 	struct list_head	inexact_bins;
 
 
-	struct sock		*nlsk;
+	struct sock		__rcu *nlsk;
 	struct sock		*nlsk_stash;
 
 	u32			sysctl_aevent_etime;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 4dd8341225bc..1656b487f833 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -35,6 +35,15 @@
 #endif
 #include <linux/unaligned.h>
 
+static struct sock *xfrm_net_nlsk(const struct net *net, const struct sk_buff *skb)
+{
+	/* get the source of this request, see netlink_unicast_kernel */
+	const struct sock *sk = NETLINK_CB(skb).sk;
+
+	/* sk is refcounted, the netns stays alive and nlsk with it */
+	return rcu_dereference_protected(net->xfrm.nlsk, sk->sk_net_refcnt);
+}
+
 static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type,
 			  struct netlink_ext_ack *extack)
 {
@@ -1727,7 +1736,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 	err = build_spdinfo(r_skb, net, sportid, seq, *flags);
 	BUG_ON(err < 0);
 
-	return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
+	return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, sportid);
 }
 
 static inline unsigned int xfrm_sadinfo_msgsize(void)
@@ -1787,7 +1796,7 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 	err = build_sadinfo(r_skb, net, sportid, seq, *flags);
 	BUG_ON(err < 0);
 
-	return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
+	return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, sportid);
 }
 
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -1807,7 +1816,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (IS_ERR(resp_skb)) {
 		err = PTR_ERR(resp_skb);
 	} else {
-		err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
+		err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
 	}
 	xfrm_state_put(x);
 out_noput:
@@ -1898,7 +1907,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		}
 	}
 
-	err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
+	err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
 
 out:
 	xfrm_state_put(x);
@@ -2543,7 +2552,7 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
 	r_up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];
 	nlmsg_end(r_skb, r_nlh);
 
-	return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
+	return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, portid);
 }
 
 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2609,7 +2618,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		if (IS_ERR(resp_skb)) {
 			err = PTR_ERR(resp_skb);
 		} else {
-			err = nlmsg_unicast(net->xfrm.nlsk, resp_skb,
+			err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb,
 					    NETLINK_CB(skb).portid);
 		}
 	} else {
@@ -2782,7 +2791,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 	err = build_aevent(r_skb, x, &c);
 	BUG_ON(err < 0);
 
-	err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid);
+	err = nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, NETLINK_CB(skb).portid);
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);
 	return err;
@@ -3486,7 +3495,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 			goto err;
 		}
 
-		err = netlink_dump_start(net->xfrm.nlsk, skb, nlh, &c);
+		err = netlink_dump_start(xfrm_net_nlsk(net, skb), skb, nlh, &c);
 		goto err;
 	}
 
-- 
2.43.0


  parent reply	other threads:[~2026-03-23  8:36 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-23  8:33 [PATCH 0/20] pull request (net): ipsec 2026-03-23 Steffen Klassert
2026-03-23  8:33 ` [PATCH 01/20] xfrm: add missing extack for XFRMA_SA_PCPU in add_acquire and allocspi Steffen Klassert
2026-03-24 14:30   ` patchwork-bot+netdevbpf
2026-03-23  8:33 ` [PATCH 02/20] xfrm: fix the condition on x->pcpu_num in xfrm_sa_len Steffen Klassert
2026-03-23  8:33 ` [PATCH 03/20] xfrm: call xdo_dev_state_delete during state update Steffen Klassert
2026-03-23  8:33 ` [PATCH 04/20] esp: fix skb leak with espintcp and async crypto Steffen Klassert
2026-03-23  8:33 ` [PATCH 05/20] xfrm: iptfs: validate inner IPv4 header length in IPTFS payload Steffen Klassert
2026-03-23  8:33 ` [PATCH 06/20] xfrm: iptfs: fix skb_put() panic on non-linear skb during reassembly Steffen Klassert
2026-03-23  8:33 ` [PATCH 07/20] xfrm: state: fix sparse warnings on xfrm_state_hold_rcu Steffen Klassert
2026-03-23  8:33 ` [PATCH 08/20] xfrm: state: fix sparse warnings in xfrm_state_init Steffen Klassert
2026-03-23  8:33 ` [PATCH 09/20] xfrm: state: fix sparse warnings around XFRM_STATE_INSERT Steffen Klassert
2026-03-23  8:33 ` [PATCH 10/20] xfrm: state: add xfrm_state_deref_prot to state_by* walk under lock Steffen Klassert
2026-03-23  8:33 ` [PATCH 11/20] xfrm: remove rcu/state_hold from xfrm_state_lookup_spi_proto Steffen Klassert
2026-03-23  8:33 ` [PATCH 12/20] xfrm: state: silence sparse warnings during netns exit Steffen Klassert
2026-03-23  8:33 ` [PATCH 13/20] xfrm: policy: fix sparse warnings in xfrm_policy_{init,fini} Steffen Klassert
2026-03-23  8:33 ` [PATCH 14/20] xfrm: policy: silence sparse warning in xfrm_policy_unregister_afinfo Steffen Klassert
2026-03-23  8:33 ` [PATCH 15/20] xfrm: add rcu_access_pointer to silence sparse warning for xfrm_input_afinfo Steffen Klassert
2026-03-23  8:33 ` Steffen Klassert [this message]
2026-03-23  8:33 ` [PATCH 17/20] xfrm: Fix work re-schedule after cancel in xfrm_nat_keepalive_net_fini() Steffen Klassert
2026-03-23  8:33 ` [PATCH 18/20] xfrm: prevent policy_hthresh.work from racing with netns teardown Steffen Klassert
2026-03-23  8:34 ` [PATCH 19/20] af_key: validate families in pfkey_send_migrate() Steffen Klassert
2026-03-23  8:34 ` [PATCH 20/20] xfrm: iptfs: only publish mode_data after clone setup Steffen Klassert
2026-03-24 11:33   ` Paolo Abeni
2026-03-24 11:52     ` Steffen Klassert
2026-03-24 12:35       ` Paolo Abeni
2026-03-24 12:40         ` Steffen Klassert
2026-03-24 14:22           ` Paolo Abeni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260323083440.2741292-17-steffen.klassert@secunet.com \
    --to=steffen.klassert@secunet.com \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox