Commit 2907c35ff64708065e5a7fd54e8ded8263eb3074
Committed by
David S. Miller
1 parent
1dcb14d9e8
Exists in
master
and in
7 other branches
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
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; |