Skip to content

Commit ddea75d

Browse files
edumazetdavem330
authored andcommitted
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>
1 parent 32f7541 commit ddea75d

1 file changed

Lines changed: 18 additions & 15 deletions

File tree

net/ipv6/ndisc.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,15 +1319,16 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
13191319
if (old_if_flags != in6_dev->if_flags)
13201320
send_ifinfo_notify = true;
13211321

1322-
if (!in6_dev->cnf.accept_ra_defrtr) {
1322+
if (!READ_ONCE(in6_dev->cnf.accept_ra_defrtr)) {
13231323
ND_PRINTK(2, info,
13241324
"RA: %s, defrtr is false for dev: %s\n",
13251325
__func__, skb->dev->name);
13261326
goto skip_defrtr;
13271327
}
13281328

13291329
lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1330-
if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_lft) {
1330+
if (lifetime != 0 &&
1331+
lifetime < READ_ONCE(in6_dev->cnf.accept_ra_min_lft)) {
13311332
ND_PRINTK(2, info,
13321333
"RA: router lifetime (%ds) is too short: %s\n",
13331334
lifetime, skb->dev->name);
@@ -1338,7 +1339,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
13381339
* accept_ra_from_local is set to true.
13391340
*/
13401341
net = dev_net(in6_dev->dev);
1341-
if (!in6_dev->cnf.accept_ra_from_local &&
1342+
if (!READ_ONCE(in6_dev->cnf.accept_ra_from_local) &&
13421343
ipv6_chk_addr(net, &ipv6_hdr(skb)->saddr, in6_dev->dev, 0)) {
13431344
ND_PRINTK(2, info,
13441345
"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)
13501351
pref = ra_msg->icmph.icmp6_router_pref;
13511352
/* 10b is handled as if it were 00b (medium) */
13521353
if (pref == ICMPV6_ROUTER_PREF_INVALID ||
1353-
!in6_dev->cnf.accept_ra_rtr_pref)
1354+
!READ_ONCE(in6_dev->cnf.accept_ra_rtr_pref))
13541355
pref = ICMPV6_ROUTER_PREF_MEDIUM;
13551356
#endif
13561357
/* 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)
14211422

14221423
spin_unlock_bh(&table->tb6_lock);
14231424
}
1424-
if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
1425+
if (READ_ONCE(in6_dev->cnf.accept_ra_min_hop_limit) < 256 &&
14251426
ra_msg->icmph.icmp6_hop_limit) {
1426-
if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
1427-
WRITE_ONCE(in6_dev->cnf.hop_limit, ra_msg->icmph.icmp6_hop_limit);
1427+
if (READ_ONCE(in6_dev->cnf.accept_ra_min_hop_limit) <=
1428+
ra_msg->icmph.icmp6_hop_limit) {
1429+
WRITE_ONCE(in6_dev->cnf.hop_limit,
1430+
ra_msg->icmph.icmp6_hop_limit);
14281431
fib6_metric_set(rt, RTAX_HOPLIMIT,
14291432
ra_msg->icmph.icmp6_hop_limit);
14301433
} else {
@@ -1506,7 +1509,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
15061509
}
15071510

15081511
#ifdef CONFIG_IPV6_ROUTE_INFO
1509-
if (!in6_dev->cnf.accept_ra_from_local &&
1512+
if (!READ_ONCE(in6_dev->cnf.accept_ra_from_local) &&
15101513
ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
15111514
in6_dev->dev, 0)) {
15121515
ND_PRINTK(2, info,
@@ -1515,7 +1518,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
15151518
goto skip_routeinfo;
15161519
}
15171520

1518-
if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
1521+
if (READ_ONCE(in6_dev->cnf.accept_ra_rtr_pref) && ndopts.nd_opts_ri) {
15191522
struct nd_opt_hdr *p;
15201523
for (p = ndopts.nd_opts_ri;
15211524
p;
@@ -1527,14 +1530,14 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
15271530
continue;
15281531
#endif
15291532
if (ri->prefix_len == 0 &&
1530-
!in6_dev->cnf.accept_ra_defrtr)
1533+
!READ_ONCE(in6_dev->cnf.accept_ra_defrtr))
15311534
continue;
15321535
if (ri->lifetime != 0 &&
1533-
ntohl(ri->lifetime) < in6_dev->cnf.accept_ra_min_lft)
1536+
ntohl(ri->lifetime) < READ_ONCE(in6_dev->cnf.accept_ra_min_lft))
15341537
continue;
1535-
if (ri->prefix_len < in6_dev->cnf.accept_ra_rt_info_min_plen)
1538+
if (ri->prefix_len < READ_ONCE(in6_dev->cnf.accept_ra_rt_info_min_plen))
15361539
continue;
1537-
if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1540+
if (ri->prefix_len > READ_ONCE(in6_dev->cnf.accept_ra_rt_info_max_plen))
15381541
continue;
15391542
rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3,
15401543
&ipv6_hdr(skb)->saddr);
@@ -1554,7 +1557,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
15541557
}
15551558
#endif
15561559

1557-
if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1560+
if (READ_ONCE(in6_dev->cnf.accept_ra_pinfo) && ndopts.nd_opts_pi) {
15581561
struct nd_opt_hdr *p;
15591562
for (p = ndopts.nd_opts_pi;
15601563
p;
@@ -1565,7 +1568,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
15651568
}
15661569
}
15671570

1568-
if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {
1571+
if (ndopts.nd_opts_mtu && READ_ONCE(in6_dev->cnf.accept_ra_mtu)) {
15691572
__be32 n;
15701573
u32 mtu;
15711574

0 commit comments

Comments
 (0)