summaryrefslogtreecommitdiffstats
path: root/net/kcm
diff options
context:
space:
mode:
authorLiping Zhang <zlpnobody@gmail.com>2017-04-17 21:18:57 +0800
committerPablo Neira Ayuso <pablo@netfilter.org>2017-04-24 20:06:28 +0200
commit53b56da83d7899de375a9de153fd7f5397de85e6 (patch)
tree28962145c0e5a76f12c59d5eeb25fb7d4f939626 /net/kcm
parent88be4c09d9008f9ff337cbf48c5d0f06c8f872e7 (diff)
downloadop-kernel-dev-53b56da83d7899de375a9de153fd7f5397de85e6.zip
op-kernel-dev-53b56da83d7899de375a9de153fd7f5397de85e6.tar.gz
netfilter: ctnetlink: make it safer when updating ct->status
After converting to use rcu for conntrack hash, one CPU may update the ct->status via ctnetlink, while another CPU may process the packets and update the ct->status. So the non-atomic operation "ct->status |= status;" via ctnetlink becomes unsafe, and this may clear the IPS_DYING_BIT bit set by another CPU unexpectedly. For example: CPU0 CPU1 ctnetlink_change_status __nf_conntrack_find_get old = ct->status nf_ct_gc_expired - nf_ct_kill - test_and_set_bit(IPS_DYING_BIT new = old | status; - ct->status = new; <-- oops, _DYING_ is cleared! Now using a series of atomic bit operation to solve the above issue. Also note, user shouldn't set IPS_TEMPLATE, IPS_SEQ_ADJUST directly, so make these two bits be unchangable too. If we set the IPS_TEMPLATE_BIT, ct will be freed by nf_ct_tmpl_free, but actually it is alloced by nf_conntrack_alloc. If we set the IPS_SEQ_ADJUST_BIT, this may cause the NULL pointer deference, as the nfct_seqadj(ct) maybe NULL. Last, add some comments to describe the logic change due to the commit a963d710f367 ("netfilter: ctnetlink: Fix regression in CTA_STATUS processing"), which makes me feel a little confusing. Fixes: 76507f69c44e ("[NETFILTER]: nf_conntrack: use RCU for conntrack hash") Signed-off-by: Liping Zhang <zlpnobody@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/kcm')
0 files changed, 0 insertions, 0 deletions
OpenPOWER on IntegriCloud