Skip to content

Commit

Permalink
net: hold rtnl again in dump callbacks
Browse files Browse the repository at this point in the history
Commit e67f88d (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 <[email protected]>
CC: Patrick McHardy <[email protected]>
CC: Stephen Hemminger <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed May 25, 2011
1 parent 1dcb14d commit 2907c35
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
1 change: 1 addition & 0 deletions net/core/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
skip:
idx++;
}
rcu_read_unlock();
cb->args[1] = idx;
rules_ops_put(ops);

Expand Down
9 changes: 7 additions & 2 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
struct nlattr *attr, *af_spec;
struct rtnl_af_ops *af_ops;

ASSERT_RTNL();
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
if (nlh == NULL)
return -EMSGSIZE;
Expand Down Expand Up @@ -1876,6 +1877,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
int min_len;
int family;
int type;
int err;

type = nlh->nlmsg_type;
if (type > RTM_MAX)
Expand All @@ -1902,8 +1904,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (dumpit == NULL)
return -EOPNOTSUPP;

__rtnl_unlock();
rtnl = net->rtnl;
return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
rtnl_lock();
return err;
}

memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
Expand Down Expand Up @@ -1975,7 +1980,7 @@ static int __net_init rtnetlink_net_init(struct net *net)
{
struct sock *sk;
sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
rtnetlink_rcv, NULL, THIS_MODULE);
rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
if (!sk)
return -ENOMEM;
net->rtnl = sk;
Expand Down

0 comments on commit 2907c35

Please sign in to comment.