netfilter: ctnetlink: fix race between delete and timeout expiration
Kerin Millar reported hardlockups while running `conntrackd -c' in a busy firewall. That system (with several processors) was acting as backup in a primary-backup setup. After several tries, I found a race condition between the deletion operation of ctnetlink and timeout expiration. This patch fixes this problem. Tested-by: Kerin Millar <kerframil@gmail.com> Reported-by: Kerin Millar <kerframil@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c577923756
commit
a16a1647fa
1 changed files with 12 additions and 11 deletions
|
@ -943,20 +943,21 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
|
|||
}
|
||||
}
|
||||
|
||||
if (nf_conntrack_event_report(IPCT_DESTROY, ct,
|
||||
NETLINK_CB(skb).pid,
|
||||
nlmsg_report(nlh)) < 0) {
|
||||
if (del_timer(&ct->timeout)) {
|
||||
if (nf_conntrack_event_report(IPCT_DESTROY, ct,
|
||||
NETLINK_CB(skb).pid,
|
||||
nlmsg_report(nlh)) < 0) {
|
||||
nf_ct_delete_from_lists(ct);
|
||||
/* we failed to report the event, try later */
|
||||
nf_ct_insert_dying_list(ct);
|
||||
nf_ct_put(ct);
|
||||
return 0;
|
||||
}
|
||||
/* death_by_timeout would report the event again */
|
||||
set_bit(IPS_DYING_BIT, &ct->status);
|
||||
nf_ct_delete_from_lists(ct);
|
||||
/* we failed to report the event, try later */
|
||||
nf_ct_insert_dying_list(ct);
|
||||
nf_ct_put(ct);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* death_by_timeout would report the event again */
|
||||
set_bit(IPS_DYING_BIT, &ct->status);
|
||||
|
||||
nf_ct_kill(ct);
|
||||
nf_ct_put(ct);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue