Skip to content

Commit a16a164

Browse files
ummakynesdavem330
authored andcommitted
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 <[email protected]> Reported-by: Kerin Millar <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c577923 commit a16a164

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

net/netfilter/nf_conntrack_netlink.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -943,20 +943,21 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
943943
}
944944
}
945945

946-
if (nf_conntrack_event_report(IPCT_DESTROY, ct,
947-
NETLINK_CB(skb).pid,
948-
nlmsg_report(nlh)) < 0) {
946+
if (del_timer(&ct->timeout)) {
947+
if (nf_conntrack_event_report(IPCT_DESTROY, ct,
948+
NETLINK_CB(skb).pid,
949+
nlmsg_report(nlh)) < 0) {
950+
nf_ct_delete_from_lists(ct);
951+
/* we failed to report the event, try later */
952+
nf_ct_insert_dying_list(ct);
953+
nf_ct_put(ct);
954+
return 0;
955+
}
956+
/* death_by_timeout would report the event again */
957+
set_bit(IPS_DYING_BIT, &ct->status);
949958
nf_ct_delete_from_lists(ct);
950-
/* we failed to report the event, try later */
951-
nf_ct_insert_dying_list(ct);
952959
nf_ct_put(ct);
953-
return 0;
954960
}
955-
956-
/* death_by_timeout would report the event again */
957-
set_bit(IPS_DYING_BIT, &ct->status);
958-
959-
nf_ct_kill(ct);
960961
nf_ct_put(ct);
961962

962963
return 0;

0 commit comments

Comments
 (0)