]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ip_tunnel: annotate data-races around t->parms.link
authorEric Dumazet <edumazet@google.com>
Tue, 13 Feb 2024 06:32:34 +0000 (06:32 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Jan 2025 12:30:00 +0000 (13:30 +0100)
[ Upstream commit f694eee9e1c00d6ca06c5e59c04e3b6ff7d64aa9 ]

t->parms.link is read locklessly, annotate these reads
and opposite writes accordingly.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: b5a7b661a073 ("net: Fix netns for ip_tunnel_init_flow()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/ipv4/ip_tunnel.c

index d56cfb6c3da4d560acac5252d62aab48f1ef91b8..196fe734ad38c090de4c70d6a0e321faea3d524b 100644 (file)
@@ -102,10 +102,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                if (!ip_tunnel_key_match(&t->parms, flags, key))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else
-                       cand = t;
+               cand = t;
        }
 
        hlist_for_each_entry_rcu(t, head, hash_node) {
@@ -117,9 +116,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                if (!ip_tunnel_key_match(&t->parms, flags, key))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else if (!cand)
+               if (!cand)
                        cand = t;
        }
 
@@ -137,9 +136,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                if (!ip_tunnel_key_match(&t->parms, flags, key))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else if (!cand)
+               if (!cand)
                        cand = t;
        }
 
@@ -150,9 +149,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                    !(t->dev->flags & IFF_UP))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else if (!cand)
+               if (!cand)
                        cand = t;
        }
 
@@ -221,7 +220,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
        hlist_for_each_entry_rcu(t, head, hash_node) {
                if (local == t->parms.iph.saddr &&
                    remote == t->parms.iph.daddr &&
-                   link == t->parms.link &&
+                   link == READ_ONCE(t->parms.link) &&
                    type == t->dev->type &&
                    ip_tunnel_key_match(&t->parms, flags, key))
                        break;
@@ -774,7 +773,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr,
                            tunnel->parms.o_key, RT_TOS(tos),
-                           dev_net(dev), tunnel->parms.link,
+                           dev_net(dev), READ_ONCE(tunnel->parms.link),
                            tunnel->fwmark, skb_get_hash(skb), 0);
 
        if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0)
@@ -894,7 +893,7 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn,
        if (t->parms.link != p->link || t->fwmark != fwmark) {
                int mtu;
 
-               t->parms.link = p->link;
+               WRITE_ONCE(t->parms.link, p->link);
                t->fwmark = fwmark;
                mtu = ip_tunnel_bind_dev(dev);
                if (set_mtu)
@@ -1084,9 +1083,9 @@ EXPORT_SYMBOL(ip_tunnel_get_link_net);
 
 int ip_tunnel_get_iflink(const struct net_device *dev)
 {
-       struct ip_tunnel *tunnel = netdev_priv(dev);
+       const struct ip_tunnel *tunnel = netdev_priv(dev);
 
-       return tunnel->parms.link;
+       return READ_ONCE(tunnel->parms.link);
 }
 EXPORT_SYMBOL(ip_tunnel_get_iflink);