Skip to content

Commit

Permalink
netfilter: nf_tables: remove catchall element in GC sync path
Browse files Browse the repository at this point in the history
[ Upstream commit 93995bf ]

The expired catchall element is not deactivated and removed from GC sync
path. This path holds mutex so just call nft_setelem_data_deactivate()
and nft_setelem_catchall_remove() before queueing the GC work.

Fixes: 4a9e12e ("netfilter: nft_set_pipapo: call nft_trans_gc_queue_sync() in catchall GC")
Reported-by: lonial con <kongln9170@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
ummakynes authored and gregkh committed Nov 28, 2023
1 parent 143f450 commit 13e2d49
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -6194,6 +6194,12 @@ static int nft_setelem_deactivate(const struct net *net,
return ret;
}

static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall)
{
list_del_rcu(&catchall->list);
kfree_rcu(catchall, rcu);
}

static void nft_setelem_catchall_remove(const struct net *net,
const struct nft_set *set,
const struct nft_set_elem *elem)
Expand All @@ -6202,8 +6208,7 @@ static void nft_setelem_catchall_remove(const struct net *net,

list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
if (catchall->elem == elem->priv) {
list_del_rcu(&catchall->list);
kfree_rcu(catchall, rcu);
nft_setelem_catchall_destroy(catchall);
break;
}
}
Expand Down Expand Up @@ -9270,11 +9275,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
unsigned int gc_seq,
bool sync)
{
struct nft_set_elem_catchall *catchall;
struct nft_set_elem_catchall *catchall, *next;
const struct nft_set *set = gc->set;
struct nft_elem_priv *elem_priv;
struct nft_set_ext *ext;

list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);

if (!nft_set_elem_expired(ext))
Expand All @@ -9292,7 +9298,17 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
if (!gc)
return NULL;

nft_trans_gc_elem_add(gc, catchall->elem);
elem_priv = catchall->elem;
if (sync) {
struct nft_set_elem elem = {
.priv = elem_priv,
};

nft_setelem_data_deactivate(gc->net, gc->set, &elem);
nft_setelem_catchall_destroy(catchall);
}

nft_trans_gc_elem_add(gc, elem_priv);
}

return gc;
Expand Down

0 comments on commit 13e2d49

Please sign in to comment.