Commit 2907c35ff64708065e5a7fd54e8ded8263eb3074

Authored by Eric Dumazet
Committed by David S. Miller
1 parent 1dcb14d9e8

net: hold rtnl again in dump callbacks

Commit e67f88dd12f6 (dont hold rtnl mutex during netlink dump callbacks)
missed fact that rtnl_fill_ifinfo() must be called with rtnl held.

Because of possible deadlocks between two mutexes (cb_mutex and rtnl),
its not easy to solve this problem, so revert this part of the patch.

It also forgot one rcu_read_unlock() in FIB dump_rules()

Add one ASSERT_RTNL() in rtnl_fill_ifinfo() to remind us the rule.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Patrick McHardy <kaber@trash.net>
CC: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 8 additions and 2 deletions Side-by-side Diff

net/core/fib_rules.c
... ... @@ -602,6 +602,7 @@
602 602 skip:
603 603 idx++;
604 604 }
  605 + rcu_read_unlock();
605 606 cb->args[1] = idx;
606 607 rules_ops_put(ops);
607 608  
net/core/rtnetlink.c
... ... @@ -850,6 +850,7 @@
850 850 struct nlattr *attr, *af_spec;
851 851 struct rtnl_af_ops *af_ops;
852 852  
  853 + ASSERT_RTNL();
853 854 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
854 855 if (nlh == NULL)
855 856 return -EMSGSIZE;
... ... @@ -1876,6 +1877,7 @@
1876 1877 int min_len;
1877 1878 int family;
1878 1879 int type;
  1880 + int err;
1879 1881  
1880 1882 type = nlh->nlmsg_type;
1881 1883 if (type > RTM_MAX)
1882 1884  
... ... @@ -1902,8 +1904,11 @@
1902 1904 if (dumpit == NULL)
1903 1905 return -EOPNOTSUPP;
1904 1906  
  1907 + __rtnl_unlock();
1905 1908 rtnl = net->rtnl;
1906   - return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
  1909 + err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
  1910 + rtnl_lock();
  1911 + return err;
1907 1912 }
1908 1913  
1909 1914 memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
... ... @@ -1975,7 +1980,7 @@
1975 1980 {
1976 1981 struct sock *sk;
1977 1982 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
1978   - rtnetlink_rcv, NULL, THIS_MODULE);
  1983 + rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
1979 1984 if (!sk)
1980 1985 return -ENOMEM;
1981 1986 net->rtnl = sk;