Commit e0bb2675 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

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: default avatarEric Dumazet <edumazet@google.com>
Acked-by: Florian Westphal <fw@strlen.de> # for netfilter parts
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e7135f48
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+1 −1
Original line number Diff line number Diff line
@@ -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;
	}

+1 −1
Original line number Diff line number Diff line
@@ -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 {
+2 −2
Original line number Diff line number Diff line
@@ -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));
+2 −2
Original line number Diff line number Diff line
@@ -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;
Loading