Skip to content

Commit 007aea7

Browse files
committed
netfilter: nf_tables: defer gc run if previous batch is still pending
jira VUlN-597 subsystem-sync netfilter:nf_tables 4.18.0-511 commit-author Florian Westphal <[email protected]> commit 8e51830 Don't queue more gc work, else we may queue the same elements multiple times. If an element is flagged as dead, this can mean that either the previous gc request was invalidated/discarded by a transaction or that the previous request is still pending in the system work queue. The latter will happen if the gc interval is set to a very low value, e.g. 1ms, and system work queue is backlogged. The sets refcount is 1 if no previous gc requeusts are queued, so add a helper for this and skip gc run if old requests are pending. Add a helper for this and skip the gc run in this case. Fixes: f6c383b ("netfilter: nf_tables: adapt set backend to use GC transaction API") Signed-off-by: Florian Westphal <[email protected]> Reviewed-by: Pablo Neira Ayuso <[email protected]> (cherry picked from commit 8e51830) Signed-off-by: Greg Rose <[email protected]>
1 parent 6b74034 commit 007aea7

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

include/net/netfilter/nf_tables.h

+5
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,11 @@ static inline void *nft_set_priv(const struct nft_set *set)
519519
return (void *)set->data;
520520
}
521521

522+
static inline bool nft_set_gc_is_pending(const struct nft_set *s)
523+
{
524+
return refcount_read(&s->refs) != 1;
525+
}
526+
522527
static inline struct nft_set *nft_set_container_of(const void *priv)
523528
{
524529
return (void *)priv - offsetof(struct nft_set, data);

net/netfilter/nft_set_hash.c

+3
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ static void nft_rhash_gc(struct work_struct *work)
308308
nft_net = nft_pernet(net);
309309
gc_seq = READ_ONCE(nft_net->gc_seq);
310310

311+
if (nft_set_gc_is_pending(set))
312+
goto done;
313+
311314
gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
312315
if (!gc)
313316
goto done;

net/netfilter/nft_set_rbtree.c

+3
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ static void nft_rbtree_gc(struct work_struct *work)
481481
nft_net = nft_pernet(net);
482482
gc_seq = READ_ONCE(nft_net->gc_seq);
483483

484+
if (nft_set_gc_is_pending(set))
485+
goto done;
486+
484487
gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
485488
if (!gc)
486489
goto done;

0 commit comments

Comments
 (0)