Commit a16a1647 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by David S. Miller

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: default avatarKerin Millar <kerframil@gmail.com>
Reported-by: default avatarKerin Millar <kerframil@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c5779237
...@@ -943,20 +943,21 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, ...@@ -943,20 +943,21 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
} }
} }
if (nf_conntrack_event_report(IPCT_DESTROY, ct, if (del_timer(&ct->timeout)) {
NETLINK_CB(skb).pid, if (nf_conntrack_event_report(IPCT_DESTROY, ct,
nlmsg_report(nlh)) < 0) { 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); nf_ct_delete_from_lists(ct);
/* we failed to report the event, try later */
nf_ct_insert_dying_list(ct);
nf_ct_put(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); nf_ct_put(ct);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment