linux/include
Liping Zhang 00834185e9 netfilter: ctnetlink: make it safer when updating ct->status
commit 53b56da83d upstream.

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 a963d710f3 ("netfilter: ctnetlink: Fix regression in CTA_STATUS
processing"), which makes me feel a little confusing.

Fixes: 76507f69c4 ("[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>
[bwh: Backported to 3.16: IPS_UNCHANGEABLE_MASK was not previously defined and
 ctnetlink_update_status() is not needed]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2017-08-26 02:14:38 +01:00
..
acpi ACPICA: Tables: Enable default 64-bit FADT addresses favor 2015-07-15 10:01:11 +01:00
asm-generic asm-generic: make get_user() clear the destination on errors 2016-11-20 01:17:26 +00:00
clocksource drivers: clocksource: add support for ARM architected timer event stream 2013-09-26 09:48:00 +01:00
crypto crypto: ahash - Fix EINPROGRESS notification callback 2017-06-05 21:17:22 +01:00
drm drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces 2017-07-18 18:40:26 +01:00
dt-bindings pinctrl: dra: dt-bindings: Fix output pull up/down 2014-11-27 11:22:05 +00:00
keys KEYS: Separate the kernel signature checking keyring from module signing 2013-09-25 17:17:01 +01:00
kvm arm/arm64: KVM: Require in-kernel vgic for the arch timers 2015-05-20 13:25:52 +01:00
linux ima: pass 'opened' flag to identify newly created files 2017-08-26 02:14:23 +01:00
math-emu math-emu: fix floating-point to integer overflow detection 2014-01-07 18:36:24 -06:00
media media: vb2: fix VBI/poll regression 2014-10-09 12:23:49 -07:00
memory ddr: add LPDDR2 data from JESD209-2 2012-05-02 00:04:06 -07:00
misc [media] altera-stapl: it is time to move out from staging 2011-09-23 15:00:57 -03:00
net net: avoid sk_forward_alloc overflows 2017-03-16 02:27:19 +00:00
pcmcia pcmcia/ds.h: introduce helper for pcmcia_driver module boilerplate 2013-03-15 12:26:03 -07:00
ras edac: add support for error type "Info" 2013-02-21 14:16:27 -03:00
rdma RDMA/core: Fix incorrect structure packing for booleans 2017-06-05 21:16:50 +01:00
rxrpc atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
scsi scsi: scsi_error: count medium access timeout only once per EH run 2017-08-26 02:14:29 +01:00
sound ALSA: rawmidi: Make snd_rawmidi_transmit() race-free 2016-02-25 00:18:43 +00:00
target target: Make EXTENDED_COPY 0xe4 failure return COPY TARGET DEVICE NOT REACHABLE 2017-02-23 03:54:18 +00:00
trace tracing: Add #undef to fix compile error 2017-07-18 18:40:06 +01:00
uapi netfilter: ctnetlink: make it safer when updating ct->status 2017-08-26 02:14:38 +01:00
video Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2014-06-12 11:32:30 -07:00
xen xen: Add RING_COPY_REQUEST() 2016-01-25 10:43:42 +00:00
Kbuild UAPI: remove empty Kbuild files 2013-04-30 17:04:09 -07:00