提交 fba143c6 编写于 作者: P Paul Moore

netns: avoid disabling irq for netns id

Bring back commit bc51dddf ("netns: avoid disabling irq for netns
id") now that we've fixed some audit multicast issues that caused
problems with original attempt.  Additional information, and history,
can be found in the links below:

 * https://github.com/linux-audit/audit-kernel/issues/22
 * https://github.com/linux-audit/audit-kernel/issues/23Signed-off-by: NCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: NPaul Moore <paul@paul-moore.com>
上级 a09cfa47
...@@ -213,14 +213,13 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id); ...@@ -213,14 +213,13 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id);
*/ */
int peernet2id_alloc(struct net *net, struct net *peer) int peernet2id_alloc(struct net *net, struct net *peer)
{ {
unsigned long flags;
bool alloc; bool alloc;
int id; int id;
spin_lock_irqsave(&net->nsid_lock, flags); spin_lock_bh(&net->nsid_lock);
alloc = atomic_read(&peer->count) == 0 ? false : true; alloc = atomic_read(&peer->count) == 0 ? false : true;
id = __peernet2id_alloc(net, peer, &alloc); id = __peernet2id_alloc(net, peer, &alloc);
spin_unlock_irqrestore(&net->nsid_lock, flags); spin_unlock_bh(&net->nsid_lock);
if (alloc && id >= 0) if (alloc && id >= 0)
rtnl_net_notifyid(net, RTM_NEWNSID, id); rtnl_net_notifyid(net, RTM_NEWNSID, id);
return id; return id;
...@@ -230,12 +229,11 @@ EXPORT_SYMBOL(peernet2id_alloc); ...@@ -230,12 +229,11 @@ EXPORT_SYMBOL(peernet2id_alloc);
/* This function returns, if assigned, the id of a peer netns. */ /* This function returns, if assigned, the id of a peer netns. */
int peernet2id(struct net *net, struct net *peer) int peernet2id(struct net *net, struct net *peer)
{ {
unsigned long flags;
int id; int id;
spin_lock_irqsave(&net->nsid_lock, flags); spin_lock_bh(&net->nsid_lock);
id = __peernet2id(net, peer); id = __peernet2id(net, peer);
spin_unlock_irqrestore(&net->nsid_lock, flags); spin_unlock_bh(&net->nsid_lock);
return id; return id;
} }
...@@ -249,18 +247,17 @@ bool peernet_has_id(struct net *net, struct net *peer) ...@@ -249,18 +247,17 @@ bool peernet_has_id(struct net *net, struct net *peer)
struct net *get_net_ns_by_id(struct net *net, int id) struct net *get_net_ns_by_id(struct net *net, int id)
{ {
unsigned long flags;
struct net *peer; struct net *peer;
if (id < 0) if (id < 0)
return NULL; return NULL;
rcu_read_lock(); rcu_read_lock();
spin_lock_irqsave(&net->nsid_lock, flags); spin_lock_bh(&net->nsid_lock);
peer = idr_find(&net->netns_ids, id); peer = idr_find(&net->netns_ids, id);
if (peer) if (peer)
get_net(peer); get_net(peer);
spin_unlock_irqrestore(&net->nsid_lock, flags); spin_unlock_bh(&net->nsid_lock);
rcu_read_unlock(); rcu_read_unlock();
return peer; return peer;
...@@ -404,17 +401,17 @@ static void cleanup_net(struct work_struct *work) ...@@ -404,17 +401,17 @@ static void cleanup_net(struct work_struct *work)
for_each_net(tmp) { for_each_net(tmp) {
int id; int id;
spin_lock_irq(&tmp->nsid_lock); spin_lock_bh(&tmp->nsid_lock);
id = __peernet2id(tmp, net); id = __peernet2id(tmp, net);
if (id >= 0) if (id >= 0)
idr_remove(&tmp->netns_ids, id); idr_remove(&tmp->netns_ids, id);
spin_unlock_irq(&tmp->nsid_lock); spin_unlock_bh(&tmp->nsid_lock);
if (id >= 0) if (id >= 0)
rtnl_net_notifyid(tmp, RTM_DELNSID, id); rtnl_net_notifyid(tmp, RTM_DELNSID, id);
} }
spin_lock_irq(&net->nsid_lock); spin_lock_bh(&net->nsid_lock);
idr_destroy(&net->netns_ids); idr_destroy(&net->netns_ids);
spin_unlock_irq(&net->nsid_lock); spin_unlock_bh(&net->nsid_lock);
} }
rtnl_unlock(); rtnl_unlock();
...@@ -542,7 +539,6 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -542,7 +539,6 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh)
{ {
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct nlattr *tb[NETNSA_MAX + 1]; struct nlattr *tb[NETNSA_MAX + 1];
unsigned long flags;
struct net *peer; struct net *peer;
int nsid, err; int nsid, err;
...@@ -563,15 +559,15 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -563,15 +559,15 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh)
if (IS_ERR(peer)) if (IS_ERR(peer))
return PTR_ERR(peer); return PTR_ERR(peer);
spin_lock_irqsave(&net->nsid_lock, flags); spin_lock_bh(&net->nsid_lock);
if (__peernet2id(net, peer) >= 0) { if (__peernet2id(net, peer) >= 0) {
spin_unlock_irqrestore(&net->nsid_lock, flags); spin_unlock_bh(&net->nsid_lock);
err = -EEXIST; err = -EEXIST;
goto out; goto out;
} }
err = alloc_netid(net, peer, nsid); err = alloc_netid(net, peer, nsid);
spin_unlock_irqrestore(&net->nsid_lock, flags); spin_unlock_bh(&net->nsid_lock);
if (err >= 0) { if (err >= 0) {
rtnl_net_notifyid(net, RTM_NEWNSID, err); rtnl_net_notifyid(net, RTM_NEWNSID, err);
err = 0; err = 0;
...@@ -693,11 +689,10 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -693,11 +689,10 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb)
.idx = 0, .idx = 0,
.s_idx = cb->args[0], .s_idx = cb->args[0],
}; };
unsigned long flags;
spin_lock_irqsave(&net->nsid_lock, flags); spin_lock_bh(&net->nsid_lock);
idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb); idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb);
spin_unlock_irqrestore(&net->nsid_lock, flags); spin_unlock_bh(&net->nsid_lock);
cb->args[0] = net_cb.idx; cb->args[0] = net_cb.idx;
return skb->len; return skb->len;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册