ipv6: annotate data-races in ndisc_router_discovery()
Annotate reads from in6_dev->cnf.XXX fields, as they could change concurrently. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
32f754176e
commit
ddea75d344
@ -1319,7 +1319,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
|
||||
if (old_if_flags != in6_dev->if_flags)
|
||||
send_ifinfo_notify = true;
|
||||
|
||||
if (!in6_dev->cnf.accept_ra_defrtr) {
|
||||
if (!READ_ONCE(in6_dev->cnf.accept_ra_defrtr)) {
|
||||
ND_PRINTK(2, info,
|
||||
"RA: %s, defrtr is false for dev: %s\n",
|
||||
__func__, skb->dev->name);
|
||||
@ -1327,7 +1327,8 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
|
||||
if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_lft) {
|
||||
if (lifetime != 0 &&
|
||||
lifetime < READ_ONCE(in6_dev->cnf.accept_ra_min_lft)) {
|
||||
ND_PRINTK(2, info,
|
||||
"RA: router lifetime (%ds) is too short: %s\n",
|
||||
lifetime, skb->dev->name);
|
||||
@ -1338,7 +1339,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
|
||||
* accept_ra_from_local is set to true.
|
||||
*/
|
||||
net = dev_net(in6_dev->dev);
|
||||
if (!in6_dev->cnf.accept_ra_from_local &&
|
||||
if (!READ_ONCE(in6_dev->cnf.accept_ra_from_local) &&
|
||||
ipv6_chk_addr(net, &ipv6_hdr(skb)->saddr, in6_dev->dev, 0)) {
|
||||
ND_PRINTK(2, info,
|
||||
"RA from local address detected on dev: %s: default router ignored\n",
|
||||
@ -1350,7 +1351,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
|
||||
pref = ra_msg->icmph.icmp6_router_pref;
|
||||
/* 10b is handled as if it were 00b (medium) */
|
||||
if (pref == ICMPV6_ROUTER_PREF_INVALID ||
|
||||
!in6_dev->cnf.accept_ra_rtr_pref)
|
||||
!READ_ONCE(in6_dev->cnf.accept_ra_rtr_pref))
|
||||
pref = ICMPV6_ROUTER_PREF_MEDIUM;
|
||||
#endif
|
||||
/* routes added from RAs do not use nexthop objects */
|
||||
@ -1421,10 +1422,12 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
|
||||
|
||||
spin_unlock_bh(&table->tb6_lock);
|
||||
}
|
||||
if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
|
||||
if (READ_ONCE(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) {
|
||||
WRITE_ONCE(in6_dev->cnf.hop_limit, ra_msg->icmph.icmp6_hop_limit);
|
||||
if (READ_ONCE(in6_dev->cnf.accept_ra_min_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 {
|
||||
@ -1506,7 +1509,7 @@ skip_linkparms:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPV6_ROUTE_INFO
|
||||
if (!in6_dev->cnf.accept_ra_from_local &&
|
||||
if (!READ_ONCE(in6_dev->cnf.accept_ra_from_local) &&
|
||||
ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
|
||||
in6_dev->dev, 0)) {
|
||||
ND_PRINTK(2, info,
|
||||
@ -1515,7 +1518,7 @@ skip_linkparms:
|
||||
goto skip_routeinfo;
|
||||
}
|
||||
|
||||
if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
|
||||
if (READ_ONCE(in6_dev->cnf.accept_ra_rtr_pref) && ndopts.nd_opts_ri) {
|
||||
struct nd_opt_hdr *p;
|
||||
for (p = ndopts.nd_opts_ri;
|
||||
p;
|
||||
@ -1527,14 +1530,14 @@ skip_linkparms:
|
||||
continue;
|
||||
#endif
|
||||
if (ri->prefix_len == 0 &&
|
||||
!in6_dev->cnf.accept_ra_defrtr)
|
||||
!READ_ONCE(in6_dev->cnf.accept_ra_defrtr))
|
||||
continue;
|
||||
if (ri->lifetime != 0 &&
|
||||
ntohl(ri->lifetime) < in6_dev->cnf.accept_ra_min_lft)
|
||||
ntohl(ri->lifetime) < READ_ONCE(in6_dev->cnf.accept_ra_min_lft))
|
||||
continue;
|
||||
if (ri->prefix_len < in6_dev->cnf.accept_ra_rt_info_min_plen)
|
||||
if (ri->prefix_len < READ_ONCE(in6_dev->cnf.accept_ra_rt_info_min_plen))
|
||||
continue;
|
||||
if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
|
||||
if (ri->prefix_len > READ_ONCE(in6_dev->cnf.accept_ra_rt_info_max_plen))
|
||||
continue;
|
||||
rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3,
|
||||
&ipv6_hdr(skb)->saddr);
|
||||
@ -1554,7 +1557,7 @@ skip_routeinfo:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
|
||||
if (READ_ONCE(in6_dev->cnf.accept_ra_pinfo) && ndopts.nd_opts_pi) {
|
||||
struct nd_opt_hdr *p;
|
||||
for (p = ndopts.nd_opts_pi;
|
||||
p;
|
||||
@ -1565,7 +1568,7 @@ skip_routeinfo:
|
||||
}
|
||||
}
|
||||
|
||||
if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {
|
||||
if (ndopts.nd_opts_mtu && READ_ONCE(in6_dev->cnf.accept_ra_mtu)) {
|
||||
__be32 n;
|
||||
u32 mtu;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user