ipv6: annotate data-races around cnf.hop_limit
authorEric Dumazet <edumazet@google.com>
Wed, 28 Feb 2024 13:54:29 +0000 (13:54 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 1 Mar 2024 08:42:31 +0000 (08:42 +0000)
idev->cnf.hop_limit and net->ipv6.devconf_all->hop_limit
might be read locklessly, add appropriate READ_ONCE()
and WRITE_ONCE() annotations.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Florian Westphal <fw@strlen.de> # for netfilter parts
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/flower/action.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/netfilter/nf_reject_ipv6.c
net/ipv6/output_core.c
net/netfilter/nf_synproxy_core.c

index 2b383d9..2c3f629 100644 (file)
@@ -460,7 +460,7 @@ nfp_fl_set_tun(struct nfp_app *app, struct nfp_fl_set_tun *set_tun,
                        set_tun->ttl = ip6_dst_hoplimit(dst);
                        dst_release(dst);
                } else {
-                       set_tun->ttl = net->ipv6.devconf_all->hop_limit;
+                       set_tun->ttl = READ_ONCE(net->ipv6.devconf_all->hop_limit);
                }
 #endif
        } else {
index 56c3c46..f61d977 100644 (file)
@@ -1346,7 +1346,7 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                }
 
                if (val < 0)
-                       val = sock_net(sk)->ipv6.devconf_all->hop_limit;
+                       val = READ_ONCE(sock_net(sk)->ipv6.devconf_all->hop_limit);
                break;
        }
 
index e96d79c..9c9c312 100644 (file)
@@ -1423,7 +1423,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
        if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
            ra_msg->icmph.icmp6_hop_limit) {
                if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
-                       in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
+                       WRITE_ONCE(in6_dev->cnf.hop_limit, ra_msg->icmph.icmp6_hop_limit);
                        fib6_metric_set(rt, RTAX_HOPLIMIT,
                                        ra_msg->icmph.icmp6_hop_limit);
                } else {
index 196dd4e..dedee26 100644 (file)
@@ -83,7 +83,7 @@ struct sk_buff *nf_reject_skb_v6_tcp_reset(struct net *net,
 
        skb_reserve(nskb, LL_MAX_HEADER);
        nip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP,
-                                    net->ipv6.devconf_all->hop_limit);
+                                    READ_ONCE(net->ipv6.devconf_all->hop_limit));
        nf_reject_ip6_tcphdr_put(nskb, oldskb, oth, otcplen);
        nip6h->payload_len = htons(nskb->len - sizeof(struct ipv6hdr));
 
@@ -124,7 +124,7 @@ struct sk_buff *nf_reject_skb_v6_unreach(struct net *net,
 
        skb_reserve(nskb, LL_MAX_HEADER);
        nip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_ICMPV6,
-                                    net->ipv6.devconf_all->hop_limit);
+                                    READ_ONCE(net->ipv6.devconf_all->hop_limit));
 
        skb_reset_transport_header(nskb);
        icmp6h = skb_put_zero(nskb, sizeof(struct icmp6hdr));
index b520531..806d4b5 100644 (file)
@@ -111,9 +111,9 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
                rcu_read_lock();
                idev = __in6_dev_get(dev);
                if (idev)
-                       hoplimit = idev->cnf.hop_limit;
+                       hoplimit = READ_ONCE(idev->cnf.hop_limit);
                else
-                       hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit;
+                       hoplimit = READ_ONCE(dev_net(dev)->ipv6.devconf_all->hop_limit);
                rcu_read_unlock();
        }
        return hoplimit;
index fbbc4fd..5b140c1 100644 (file)
@@ -800,7 +800,7 @@ synproxy_build_ip_ipv6(struct net *net, struct sk_buff *skb,
        skb_reset_network_header(skb);
        iph = skb_put(skb, sizeof(*iph));
        ip6_flow_hdr(iph, 0, 0);
-       iph->hop_limit  = net->ipv6.devconf_all->hop_limit;
+       iph->hop_limit  = READ_ONCE(net->ipv6.devconf_all->hop_limit);
        iph->nexthdr    = IPPROTO_TCP;
        iph->saddr      = *saddr;
        iph->daddr      = *daddr;