summaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2019-05-31 12:27:09 -0400
committerDavid S. Miller <davem@davemloft.net>2019-06-02 21:08:36 -0400
commit2638eb8b50cfc16240e0bb080b9afbf541a9b39d (patch)
tree84264a6f50aaedfac6854bef3d5972926d321c10 /net/ipv4/devinet.c
parentcb8f1478cea68bc9c9bca8bded9617d9b0b7beb6 (diff)
net: ipv4: provide __rcu annotation for ifa_list
ifa_list is protected by rcu, yet code doesn't reflect this. Add the __rcu annotations and fix up all places that are now reported by sparse. I've done this in the same commit to not add intermediate patches that result in new warnings. Reported-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index b45421b2b734..ebaea05b4033 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -194,7 +194,8 @@ static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);
194 194
195static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); 195static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
196static BLOCKING_NOTIFIER_HEAD(inetaddr_validator_chain); 196static BLOCKING_NOTIFIER_HEAD(inetaddr_validator_chain);
197static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 197static void inet_del_ifa(struct in_device *in_dev,
198 struct in_ifaddr __rcu **ifap,
198 int destroy); 199 int destroy);
199#ifdef CONFIG_SYSCTL 200#ifdef CONFIG_SYSCTL
200static int devinet_sysctl_register(struct in_device *idev); 201static int devinet_sysctl_register(struct in_device *idev);
@@ -300,8 +301,8 @@ static void in_dev_rcu_put(struct rcu_head *head)
300 301
301static void inetdev_destroy(struct in_device *in_dev) 302static void inetdev_destroy(struct in_device *in_dev)
302{ 303{
303 struct in_ifaddr *ifa;
304 struct net_device *dev; 304 struct net_device *dev;
305 struct in_ifaddr *ifa;
305 306
306 ASSERT_RTNL(); 307 ASSERT_RTNL();
307 308
@@ -311,7 +312,7 @@ static void inetdev_destroy(struct in_device *in_dev)
311 312
312 ip_mc_destroy_dev(in_dev); 313 ip_mc_destroy_dev(in_dev);
313 314
314 while ((ifa = in_dev->ifa_list) != NULL) { 315 while ((ifa = rtnl_dereference(in_dev->ifa_list)) != NULL) {
315 inet_del_ifa(in_dev, &in_dev->ifa_list, 0); 316 inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
316 inet_free_ifa(ifa); 317 inet_free_ifa(ifa);
317 } 318 }
@@ -342,17 +343,20 @@ int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
342 return 0; 343 return 0;
343} 344}
344 345
345static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 346static void __inet_del_ifa(struct in_device *in_dev,
346 int destroy, struct nlmsghdr *nlh, u32 portid) 347 struct in_ifaddr __rcu **ifap,
348 int destroy, struct nlmsghdr *nlh, u32 portid)
347{ 349{
348 struct in_ifaddr *promote = NULL; 350 struct in_ifaddr *promote = NULL;
349 struct in_ifaddr *ifa, *ifa1 = *ifap; 351 struct in_ifaddr *ifa, *ifa1;
350 struct in_ifaddr *last_prim = in_dev->ifa_list; 352 struct in_ifaddr *last_prim;
351 struct in_ifaddr *prev_prom = NULL; 353 struct in_ifaddr *prev_prom = NULL;
352 int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev); 354 int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev);
353 355
354 ASSERT_RTNL(); 356 ASSERT_RTNL();
355 357
358 ifa1 = rtnl_dereference(*ifap);
359 last_prim = rtnl_dereference(in_dev->ifa_list);
356 if (in_dev->dead) 360 if (in_dev->dead)
357 goto no_promotions; 361 goto no_promotions;
358 362
@@ -361,9 +365,9 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
361 **/ 365 **/
362 366
363 if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { 367 if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
364 struct in_ifaddr **ifap1 = &ifa1->ifa_next; 368 struct in_ifaddr __rcu **ifap1 = &ifa1->ifa_next;
365 369
366 while ((ifa = *ifap1) != NULL) { 370 while ((ifa = rtnl_dereference(*ifap1)) != NULL) {
367 if (!(ifa->ifa_flags & IFA_F_SECONDARY) && 371 if (!(ifa->ifa_flags & IFA_F_SECONDARY) &&
368 ifa1->ifa_scope <= ifa->ifa_scope) 372 ifa1->ifa_scope <= ifa->ifa_scope)
369 last_prim = ifa; 373 last_prim = ifa;
@@ -396,7 +400,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
396 * and later to add them back with new prefsrc. Do this 400 * and later to add them back with new prefsrc. Do this
397 * while all addresses are on the device list. 401 * while all addresses are on the device list.
398 */ 402 */
399 for (ifa = promote; ifa; ifa = ifa->ifa_next) { 403 for (ifa = promote; ifa; ifa = rtnl_dereference(ifa->ifa_next)) {
400 if (ifa1->ifa_mask == ifa->ifa_mask && 404 if (ifa1->ifa_mask == ifa->ifa_mask &&
401 inet_ifa_match(ifa1->ifa_address, ifa)) 405 inet_ifa_match(ifa1->ifa_address, ifa))
402 fib_del_ifaddr(ifa, ifa1); 406 fib_del_ifaddr(ifa, ifa1);
@@ -422,19 +426,24 @@ no_promotions:
422 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); 426 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
423 427
424 if (promote) { 428 if (promote) {
425 struct in_ifaddr *next_sec = promote->ifa_next; 429 struct in_ifaddr *next_sec;
426 430
431 next_sec = rtnl_dereference(promote->ifa_next);
427 if (prev_prom) { 432 if (prev_prom) {
428 prev_prom->ifa_next = promote->ifa_next; 433 struct in_ifaddr *last_sec;
429 promote->ifa_next = last_prim->ifa_next; 434
430 last_prim->ifa_next = promote; 435 last_sec = rtnl_dereference(last_prim->ifa_next);
436 rcu_assign_pointer(prev_prom->ifa_next, next_sec);
437 rcu_assign_pointer(promote->ifa_next, last_sec);
438 rcu_assign_pointer(last_prim->ifa_next, promote);
431 } 439 }
432 440
433 promote->ifa_flags &= ~IFA_F_SECONDARY; 441 promote->ifa_flags &= ~IFA_F_SECONDARY;
434 rtmsg_ifa(RTM_NEWADDR, promote, nlh, portid); 442 rtmsg_ifa(RTM_NEWADDR, promote, nlh, portid);
435 blocking_notifier_call_chain(&inetaddr_chain, 443 blocking_notifier_call_chain(&inetaddr_chain,
436 NETDEV_UP, promote); 444 NETDEV_UP, promote);
437 for (ifa = next_sec; ifa; ifa = ifa->ifa_next) { 445 for (ifa = next_sec; ifa;
446 ifa = rtnl_dereference(ifa->ifa_next)) {
438 if (ifa1->ifa_mask != ifa->ifa_mask || 447 if (ifa1->ifa_mask != ifa->ifa_mask ||
439 !inet_ifa_match(ifa1->ifa_address, ifa)) 448 !inet_ifa_match(ifa1->ifa_address, ifa))
440 continue; 449 continue;
@@ -446,7 +455,8 @@ no_promotions:
446 inet_free_ifa(ifa1); 455 inet_free_ifa(ifa1);
447} 456}
448 457
449static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 458static void inet_del_ifa(struct in_device *in_dev,
459 struct in_ifaddr __rcu **ifap,
450 int destroy) 460 int destroy)
451{ 461{
452 __inet_del_ifa(in_dev, ifap, destroy, NULL, 0); 462 __inet_del_ifa(in_dev, ifap, destroy, NULL, 0);
@@ -459,9 +469,10 @@ static DECLARE_DELAYED_WORK(check_lifetime_work, check_lifetime);
459static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh, 469static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
460 u32 portid, struct netlink_ext_ack *extack) 470 u32 portid, struct netlink_ext_ack *extack)
461{ 471{
472 struct in_ifaddr __rcu **last_primary, **ifap;
462 struct in_device *in_dev = ifa->ifa_dev; 473 struct in_device *in_dev = ifa->ifa_dev;
463 struct in_ifaddr *ifa1, **ifap, **last_primary;
464 struct in_validator_info ivi; 474 struct in_validator_info ivi;
475 struct in_ifaddr *ifa1;
465 int ret; 476 int ret;
466 477
467 ASSERT_RTNL(); 478 ASSERT_RTNL();
@@ -474,8 +485,10 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
474 ifa->ifa_flags &= ~IFA_F_SECONDARY; 485 ifa->ifa_flags &= ~IFA_F_SECONDARY;
475 last_primary = &in_dev->ifa_list; 486 last_primary = &in_dev->ifa_list;
476 487
477 for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL; 488 ifap = &in_dev->ifa_list;
478 ifap = &ifa1->ifa_next) { 489 ifa1 = rtnl_dereference(*ifap);
490
491 while (ifa1) {
479 if (!(ifa1->ifa_flags & IFA_F_SECONDARY) && 492 if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&
480 ifa->ifa_scope <= ifa1->ifa_scope) 493 ifa->ifa_scope <= ifa1->ifa_scope)
481 last_primary = &ifa1->ifa_next; 494 last_primary = &ifa1->ifa_next;
@@ -491,6 +504,9 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
491 } 504 }
492 ifa->ifa_flags |= IFA_F_SECONDARY; 505 ifa->ifa_flags |= IFA_F_SECONDARY;
493 } 506 }
507
508 ifap = &ifa1->ifa_next;
509 ifa1 = rtnl_dereference(*ifap);
494 } 510 }
495 511
496 /* Allow any devices that wish to register ifaddr validtors to weigh 512 /* Allow any devices that wish to register ifaddr validtors to weigh
@@ -516,8 +532,8 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
516 ifap = last_primary; 532 ifap = last_primary;
517 } 533 }
518 534
519 ifa->ifa_next = *ifap; 535 rcu_assign_pointer(ifa->ifa_next, *ifap);
520 *ifap = ifa; 536 rcu_assign_pointer(*ifap, ifa);
521 537
522 inet_hash_insert(dev_net(in_dev->dev), ifa); 538 inet_hash_insert(dev_net(in_dev->dev), ifa);
523 539
@@ -617,10 +633,12 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
617 struct netlink_ext_ack *extack) 633 struct netlink_ext_ack *extack)
618{ 634{
619 struct net *net = sock_net(skb->sk); 635 struct net *net = sock_net(skb->sk);
636 struct in_ifaddr __rcu **ifap;
620 struct nlattr *tb[IFA_MAX+1]; 637 struct nlattr *tb[IFA_MAX+1];
621 struct in_device *in_dev; 638 struct in_device *in_dev;
622 struct ifaddrmsg *ifm; 639 struct ifaddrmsg *ifm;
623 struct in_ifaddr *ifa, **ifap; 640 struct in_ifaddr *ifa;
641
624 int err = -EINVAL; 642 int err = -EINVAL;
625 643
626 ASSERT_RTNL(); 644 ASSERT_RTNL();
@@ -637,7 +655,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
637 goto errout; 655 goto errout;
638 } 656 }
639 657
640 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 658 for (ifap = &in_dev->ifa_list; (ifa = rtnl_dereference(*ifap)) != NULL;
641 ifap = &ifa->ifa_next) { 659 ifap = &ifa->ifa_next) {
642 if (tb[IFA_LOCAL] && 660 if (tb[IFA_LOCAL] &&
643 ifa->ifa_local != nla_get_in_addr(tb[IFA_LOCAL])) 661 ifa->ifa_local != nla_get_in_addr(tb[IFA_LOCAL]))
@@ -725,15 +743,20 @@ static void check_lifetime(struct work_struct *work)
725 743
726 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && 744 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
727 age >= ifa->ifa_valid_lft) { 745 age >= ifa->ifa_valid_lft) {
728 struct in_ifaddr **ifap; 746 struct in_ifaddr __rcu **ifap;
729 747 struct in_ifaddr *tmp;
730 for (ifap = &ifa->ifa_dev->ifa_list; 748
731 *ifap != NULL; ifap = &(*ifap)->ifa_next) { 749 ifap = &ifa->ifa_dev->ifa_list;
732 if (*ifap == ifa) { 750 tmp = rtnl_dereference(*ifap);
751 while (tmp) {
752 tmp = rtnl_dereference(tmp->ifa_next);
753 if (rtnl_dereference(*ifap) == ifa) {
733 inet_del_ifa(ifa->ifa_dev, 754 inet_del_ifa(ifa->ifa_dev,
734 ifap, 1); 755 ifap, 1);
735 break; 756 break;
736 } 757 }
758 ifap = &tmp->ifa_next;
759 tmp = rtnl_dereference(*ifap);
737 } 760 }
738 } else if (ifa->ifa_preferred_lft != 761 } else if (ifa->ifa_preferred_lft !=
739 INFINITY_LIFE_TIME && 762 INFINITY_LIFE_TIME &&
@@ -977,8 +1000,8 @@ int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
977{ 1000{
978 struct sockaddr_in sin_orig; 1001 struct sockaddr_in sin_orig;
979 struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr; 1002 struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr;
1003 struct in_ifaddr __rcu **ifap = NULL;
980 struct in_device *in_dev; 1004 struct in_device *in_dev;
981 struct in_ifaddr **ifap = NULL;
982 struct in_ifaddr *ifa = NULL; 1005 struct in_ifaddr *ifa = NULL;
983 struct net_device *dev; 1006 struct net_device *dev;
984 char *colon; 1007 char *colon;
@@ -1049,7 +1072,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
1049 /* note: we only do this for a limited set of ioctls 1072 /* note: we only do this for a limited set of ioctls
1050 and only if the original address family was AF_INET. 1073 and only if the original address family was AF_INET.
1051 This is checked above. */ 1074 This is checked above. */
1052 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 1075
1076 for (ifap = &in_dev->ifa_list;
1077 (ifa = rtnl_dereference(*ifap)) != NULL;
1053 ifap = &ifa->ifa_next) { 1078 ifap = &ifa->ifa_next) {
1054 if (!strcmp(ifr->ifr_name, ifa->ifa_label) && 1079 if (!strcmp(ifr->ifr_name, ifa->ifa_label) &&
1055 sin_orig.sin_addr.s_addr == 1080 sin_orig.sin_addr.s_addr ==
@@ -1062,7 +1087,8 @@ int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
1062 4.3BSD-style and passed in junk so we fall back to 1087 4.3BSD-style and passed in junk so we fall back to
1063 comparing just the label */ 1088 comparing just the label */
1064 if (!ifa) { 1089 if (!ifa) {
1065 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 1090 for (ifap = &in_dev->ifa_list;
1091 (ifa = rtnl_dereference(*ifap)) != NULL;
1066 ifap = &ifa->ifa_next) 1092 ifap = &ifa->ifa_next)
1067 if (!strcmp(ifr->ifr_name, ifa->ifa_label)) 1093 if (!strcmp(ifr->ifr_name, ifa->ifa_label))
1068 break; 1094 break;