linux-stable/include
Pablo Neira Ayuso 0624f190b5 netfilter: nf_tables: GC transaction API to avoid race with control plane
commit 5f68718b34 upstream.

The set types rhashtable and rbtree use a GC worker to reclaim memory.
From system work queue, in periodic intervals, a scan of the table is
done.

The major caveat here is that the nft transaction mutex is not held.
This causes a race between control plane and GC when they attempt to
delete the same element.

We cannot grab the netlink mutex from the work queue, because the
control plane has to wait for the GC work queue in case the set is to be
removed, so we get following deadlock:

   cpu 1                                cpu2
     GC work                            transaction comes in , lock nft mutex
       `acquire nft mutex // BLOCKS
                                        transaction asks to remove the set
                                        set destruction calls cancel_work_sync()

cancel_work_sync will now block forever, because it is waiting for the
mutex the caller already owns.

This patch adds a new API that deals with garbage collection in two
steps:

1) Lockless GC of expired elements sets on the NFT_SET_ELEM_DEAD_BIT
   so they are not visible via lookup. Annotate current GC sequence in
   the GC transaction. Enqueue GC transaction work as soon as it is
   full. If ruleset is updated, then GC transaction is aborted and
   retried later.

2) GC work grabs the mutex. If GC sequence has changed then this GC
   transaction lost race with control plane, abort it as it contains
   stale references to objects and let GC try again later. If the
   ruleset is intact, then this GC transaction deactivates and removes
   the elements and it uses call_rcu() to destroy elements.

Note that no elements are removed from GC lockless path, the _DEAD bit
is set and pointers are collected. GC catchall does not remove the
elements anymore too. There is a new set->dead flag that is set on to
abort the GC transaction to deal with set->ops->destroy() path which
removes the remaining elements in the set from commit_release, where no
mutex is held.

To deal with GC when mutex is held, which allows safe deactivate and
removal, add sync GC API which releases the set element object via
call_rcu(). This is used by rbtree and pipapo backends which also
perform garbage collection from control plane path.

Since element removal from sets can happen from control plane and
element garbage collection/timeout, it is necessary to keep the set
structure alive until all elements have been deactivated and destroyed.

We cannot do a cancel_work_sync or flush_work in nft_set_destroy because
its called with the transaction mutex held, but the aforementioned async
work queue might be blocked on the very mutex that nft_set_destroy()
callchain is sitting on.

This gives us the choice of ABBA deadlock or UaF.

To avoid both, add set->refs refcount_t member. The GC API can then
increment the set refcount and release it once the elements have been
free'd.

Set backends are adapted to use the GC transaction API in a follow up
patch entitled:

  ("netfilter: nf_tables: use gc transaction API in set backends")

This is joint work with Florian Westphal.

Fixes: cfed7e1b1f ("netfilter: nf_tables: add set garbage collection helpers")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-08-16 18:32:22 +02:00
..
acpi ACPI: sleep: Avoid breaking S3 wakeup due to might_sleep() 2023-06-15 18:05:19 +02:00
asm-generic word-at-a-time: use the same return type for has_zero regardless of endianness 2023-08-11 12:14:08 +02:00
clocksource
crypto
drm drm/dp_mst: Clear MSG_RDY flag before sending new message 2023-07-23 13:54:02 +02:00
dt-bindings dt-bindings: power: qcom,rpmpd: Add SA8155P 2023-05-24 20:34:49 -07:00
keys
kunit
kvm KVM: arm64: vgic-v4: Make the doorbell request robust w.r.t preemption 2023-07-27 08:56:43 +02:00
linux x86/speculation: Add cpu_show_gds() prototype 2023-08-16 18:32:22 +02:00
math-emu
media Revert "media: dvb-core: Fix use-after-free on race condition at dvb_frontend" 2023-06-14 23:16:29 +01:00
memory
misc
net netfilter: nf_tables: GC transaction API to avoid race with control plane 2023-08-16 18:32:22 +02:00
pcmcia
ras
rdma RDMA/cma: Always set static rate to 0 for RoCE 2023-06-11 11:26:02 +03:00
rv
scsi
soc net: dsa: felix: make vsc9959_tas_guard_bands_update() visible to ocelot->ops 2023-07-23 13:53:40 +02:00
sound ASoC: Intel: avs: Account for UID of ACPI device 2023-05-22 11:18:24 +01:00
target scsi: target: iscsi: Remove unused transport_timer 2023-05-22 16:29:39 -04:00
trace net: fix net_dev_start_xmit trace event vs skb_transport_offset() 2023-07-19 16:36:46 +02:00
uapi block: Fix a source code comment in include/uapi/linux/blkzoned.h 2023-08-03 10:25:57 +02:00
ufs scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command 2023-07-19 16:36:16 +02:00
vdso
video
xen