ipv6: annotate data-races around cnf.hop_limit

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>
This commit is contained in:
Eric Dumazet 2024-02-28 13:54:29 +00:00 committed by David S. Miller
parent e7135f4849
commit e0bb2675fe
6 changed files with 8 additions and 8 deletions

View 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); set_tun->ttl = ip6_dst_hoplimit(dst);
dst_release(dst); dst_release(dst);
} else { } else {
set_tun->ttl = net->ipv6.devconf_all->hop_limit; set_tun->ttl = READ_ONCE(net->ipv6.devconf_all->hop_limit);
} }
#endif #endif
} else { } else {

View File

@ -1346,7 +1346,7 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
} }
if (val < 0) if (val < 0)
val = sock_net(sk)->ipv6.devconf_all->hop_limit; val = READ_ONCE(sock_net(sk)->ipv6.devconf_all->hop_limit);
break; break;
} }

View 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 && if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
ra_msg->icmph.icmp6_hop_limit) { ra_msg->icmph.icmp6_hop_limit) {
if (in6_dev->cnf.accept_ra_min_hop_limit <= 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, fib6_metric_set(rt, RTAX_HOPLIMIT,
ra_msg->icmph.icmp6_hop_limit); ra_msg->icmph.icmp6_hop_limit);
} else { } else {

View File

@ -83,7 +83,7 @@ struct sk_buff *nf_reject_skb_v6_tcp_reset(struct net *net,
skb_reserve(nskb, LL_MAX_HEADER); skb_reserve(nskb, LL_MAX_HEADER);
nip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, 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); nf_reject_ip6_tcphdr_put(nskb, oldskb, oth, otcplen);
nip6h->payload_len = htons(nskb->len - sizeof(struct ipv6hdr)); 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); skb_reserve(nskb, LL_MAX_HEADER);
nip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_ICMPV6, 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); skb_reset_transport_header(nskb);
icmp6h = skb_put_zero(nskb, sizeof(struct icmp6hdr)); icmp6h = skb_put_zero(nskb, sizeof(struct icmp6hdr));

View File

@ -111,9 +111,9 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
rcu_read_lock(); rcu_read_lock();
idev = __in6_dev_get(dev); idev = __in6_dev_get(dev);
if (idev) if (idev)
hoplimit = idev->cnf.hop_limit; hoplimit = READ_ONCE(idev->cnf.hop_limit);
else else
hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit; hoplimit = READ_ONCE(dev_net(dev)->ipv6.devconf_all->hop_limit);
rcu_read_unlock(); rcu_read_unlock();
} }
return hoplimit; return hoplimit;

View File

@ -800,7 +800,7 @@ synproxy_build_ip_ipv6(struct net *net, struct sk_buff *skb,
skb_reset_network_header(skb); skb_reset_network_header(skb);
iph = skb_put(skb, sizeof(*iph)); iph = skb_put(skb, sizeof(*iph));
ip6_flow_hdr(iph, 0, 0); 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->nexthdr = IPPROTO_TCP;
iph->saddr = *saddr; iph->saddr = *saddr;
iph->daddr = *daddr; iph->daddr = *daddr;