Commit 2dce8c52 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

net: dst: annotate data-races around dst->output



dst_dev_put() can overwrite dst->output while other
cpus might read this field (for instance from dst_output())

Add READ_ONCE()/WRITE_ONCE() annotations to suppress
potential issues.

We will likely need RCU protection in the future.

Fixes: 4a6ce2b6 ("net: introduce a new function dst_dev_put()")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250630121934.3399505-6-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f1c5fd34
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -458,7 +458,7 @@ INDIRECT_CALLABLE_DECLARE(int ip_output(struct net *, struct sock *,
/* Output packet to network from transport.  */
static inline int dst_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	return INDIRECT_CALL_INET(skb_dst(skb)->output,
	return INDIRECT_CALL_INET(READ_ONCE(skb_dst(skb)->output),
				  ip6_output, ip_output,
				  net, sk, skb);
}
+2 −2
Original line number Diff line number Diff line
@@ -138,8 +138,8 @@ int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len,
static inline void lwtunnel_set_redirect(struct dst_entry *dst)
{
	if (lwtunnel_output_redirect(dst->lwtstate)) {
		dst->lwtstate->orig_output = dst->output;
		dst->output = lwtunnel_output;
		dst->lwtstate->orig_output = READ_ONCE(dst->output);
		WRITE_ONCE(dst->output, lwtunnel_output);
	}
	if (lwtunnel_input_redirect(dst->lwtstate)) {
		dst->lwtstate->orig_input = READ_ONCE(dst->input);
+1 −1
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ void dst_dev_put(struct dst_entry *dst)
	if (dst->ops->ifdown)
		dst->ops->ifdown(dst, dev);
	WRITE_ONCE(dst->input, dst_discard);
	dst->output = dst_discard_out;
	WRITE_ONCE(dst->output, dst_discard_out);
	dst->dev = blackhole_netdev;
	netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
			   GFP_ATOMIC);
+1 −1
Original line number Diff line number Diff line
@@ -1688,7 +1688,7 @@ struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt)
			new_rt->rt_gw6 = rt->rt_gw6;

		new_rt->dst.input = READ_ONCE(rt->dst.input);
		new_rt->dst.output = rt->dst.output;
		new_rt->dst.output = READ_ONCE(rt->dst.output);
		new_rt->dst.error = rt->dst.error;
		new_rt->dst.lastuse = jiffies;
		new_rt->dst.lwtstate = lwtstate_get(rt->dst.lwtstate);