Skip to content

Commit 58b5613

Browse files
ummakynesshaoyingxu
authored andcommitted
netfilter: nf_tables: remove catchall element in GC sync path
[ 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: Puranjay Mohan <pjy@amazon.com>
1 parent 6b7ef3e commit 58b5613

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6049,6 +6049,12 @@ static int nft_setelem_deactivate(const struct net *net,
60496049
return ret;
60506050
}
60516051

6052+
static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall)
6053+
{
6054+
list_del_rcu(&catchall->list);
6055+
kfree_rcu(catchall, rcu);
6056+
}
6057+
60526058
static void nft_setelem_catchall_remove(const struct net *net,
60536059
const struct nft_set *set,
60546060
const struct nft_set_elem *elem)
@@ -6057,8 +6063,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
60576063

60586064
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
60596065
if (catchall->elem == elem->priv) {
6060-
list_del_rcu(&catchall->list);
6061-
kfree_rcu(catchall, rcu);
6066+
nft_setelem_catchall_destroy(catchall);
60626067
break;
60636068
}
60646069
}
@@ -9046,11 +9051,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
90469051
unsigned int gc_seq,
90479052
bool sync)
90489053
{
9049-
struct nft_set_elem_catchall *catchall;
9054+
struct nft_set_elem_catchall *catchall, *next;
90509055
const struct nft_set *set = gc->set;
9056+
struct nft_elem_priv *elem_priv;
90519057
struct nft_set_ext *ext;
90529058

9053-
list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
9059+
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
90549060
ext = nft_set_elem_ext(set, catchall->elem);
90559061

90569062
if (!nft_set_elem_expired(ext))
@@ -9068,7 +9074,17 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
90689074
if (!gc)
90699075
return NULL;
90709076

9071-
nft_trans_gc_elem_add(gc, catchall->elem);
9077+
elem_priv = catchall->elem;
9078+
if (sync) {
9079+
struct nft_set_elem elem = {
9080+
.priv = elem_priv,
9081+
};
9082+
9083+
nft_setelem_data_deactivate(gc->net, gc->set, &elem);
9084+
nft_setelem_catchall_destroy(catchall);
9085+
}
9086+
9087+
nft_trans_gc_elem_add(gc, elem_priv);
90729088
}
90739089

90749090
return gc;

0 commit comments

Comments
 (0)