mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
UPSTREAM: netfilter: nf_tables: remove catchall element in GC sync path
[ Upstream commit 93995bf4af2c5a99e2a87f0cd5ce547d31eb7630 ] 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. Bug: 310691882 Fixes:4a9e12ea7e("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> (cherry picked from commit13e2d49647) Signed-off-by: Lee Jones <joneslee@google.com> Change-Id: Ic5d1d98fe5a749e759869f0789cbb77c4ab5e6c2
This commit is contained in:
committed by
Treehugger Robot
parent
924116f1b8
commit
72bdb74622
@@ -6198,6 +6198,12 @@ static int nft_setelem_deactivate(const struct net *net,
|
|||||||
return ret;
|
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,
|
static void nft_setelem_catchall_remove(const struct net *net,
|
||||||
const struct nft_set *set,
|
const struct nft_set *set,
|
||||||
const struct nft_set_elem *elem)
|
const struct nft_set_elem *elem)
|
||||||
@@ -6206,8 +6212,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
|
|||||||
|
|
||||||
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
|
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
|
||||||
if (catchall->elem == elem->priv) {
|
if (catchall->elem == elem->priv) {
|
||||||
list_del_rcu(&catchall->list);
|
nft_setelem_catchall_destroy(catchall);
|
||||||
kfree_rcu(catchall, rcu);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9268,11 +9273,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
|
|||||||
unsigned int gc_seq,
|
unsigned int gc_seq,
|
||||||
bool sync)
|
bool sync)
|
||||||
{
|
{
|
||||||
struct nft_set_elem_catchall *catchall;
|
struct nft_set_elem_catchall *catchall, *next;
|
||||||
const struct nft_set *set = gc->set;
|
const struct nft_set *set = gc->set;
|
||||||
|
struct nft_elem_priv *elem_priv;
|
||||||
struct nft_set_ext *ext;
|
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);
|
ext = nft_set_elem_ext(set, catchall->elem);
|
||||||
|
|
||||||
if (!nft_set_elem_expired(ext))
|
if (!nft_set_elem_expired(ext))
|
||||||
@@ -9290,7 +9296,17 @@ dead_elem:
|
|||||||
if (!gc)
|
if (!gc)
|
||||||
return NULL;
|
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;
|
return gc;
|
||||||
|
|||||||
Reference in New Issue
Block a user