Skip to content

Commit 93995bf

Browse files
committed
netfilter: nf_tables: remove catchall element in GC sync path
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 <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 94090b2 commit 93995bf

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6520,6 +6520,12 @@ static int nft_setelem_deactivate(const struct net *net,
65206520
return ret;
65216521
}
65226522

6523+
static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall)
6524+
{
6525+
list_del_rcu(&catchall->list);
6526+
kfree_rcu(catchall, rcu);
6527+
}
6528+
65236529
static void nft_setelem_catchall_remove(const struct net *net,
65246530
const struct nft_set *set,
65256531
struct nft_elem_priv *elem_priv)
@@ -6528,8 +6534,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
65286534

65296535
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
65306536
if (catchall->elem == elem_priv) {
6531-
list_del_rcu(&catchall->list);
6532-
kfree_rcu(catchall, rcu);
6537+
nft_setelem_catchall_destroy(catchall);
65336538
break;
65346539
}
65356540
}
@@ -9678,11 +9683,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
96789683
unsigned int gc_seq,
96799684
bool sync)
96809685
{
9681-
struct nft_set_elem_catchall *catchall;
9686+
struct nft_set_elem_catchall *catchall, *next;
96829687
const struct nft_set *set = gc->set;
9688+
struct nft_elem_priv *elem_priv;
96839689
struct nft_set_ext *ext;
96849690

9685-
list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
9691+
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
96869692
ext = nft_set_elem_ext(set, catchall->elem);
96879693

96889694
if (!nft_set_elem_expired(ext))
@@ -9700,7 +9706,13 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
97009706
if (!gc)
97019707
return NULL;
97029708

9703-
nft_trans_gc_elem_add(gc, catchall->elem);
9709+
elem_priv = catchall->elem;
9710+
if (sync) {
9711+
nft_setelem_data_deactivate(gc->net, gc->set, elem_priv);
9712+
nft_setelem_catchall_destroy(catchall);
9713+
}
9714+
9715+
nft_trans_gc_elem_add(gc, elem_priv);
97049716
}
97059717

97069718
return gc;

0 commit comments

Comments
 (0)