Skip to content

Commit 1b3a51c

Browse files
committed
netfilter: nf_tables: remove catchall element in GC sync path
cve CVE-2023-6111 commit-author Pablo Neira Ayuso <[email protected]> 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 <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> (cherry picked from commit 93995bf) Signed-off-by: Marcin Wcisło <[email protected]>
1 parent a35dbfa commit 1b3a51c

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
@@ -6223,6 +6223,12 @@ static int nft_setelem_deactivate(const struct net *net,
62236223
return ret;
62246224
}
62256225

6226+
static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall)
6227+
{
6228+
list_del_rcu(&catchall->list);
6229+
kfree_rcu(catchall, rcu);
6230+
}
6231+
62266232
static void nft_setelem_catchall_remove(const struct net *net,
62276233
const struct nft_set *set,
62286234
const struct nft_set_elem *elem)
@@ -6231,8 +6237,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
62316237

62326238
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
62336239
if (catchall->elem == elem->priv) {
6234-
list_del_rcu(&catchall->list);
6235-
kfree_rcu(catchall, rcu);
6240+
nft_setelem_catchall_destroy(catchall);
62366241
break;
62376242
}
62386243
}
@@ -9295,11 +9300,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
92959300
unsigned int gc_seq,
92969301
bool sync)
92979302
{
9298-
struct nft_set_elem_catchall *catchall;
9303+
struct nft_set_elem_catchall *catchall, *next;
92999304
const struct nft_set *set = gc->set;
9305+
struct nft_elem_priv *elem_priv;
93009306
struct nft_set_ext *ext;
93019307

9302-
list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
9308+
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
93039309
ext = nft_set_elem_ext(set, catchall->elem);
93049310

93059311
if (!nft_set_elem_expired(ext))
@@ -9317,7 +9323,17 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
93179323
if (!gc)
93189324
return NULL;
93199325

9320-
nft_trans_gc_elem_add(gc, catchall->elem);
9326+
elem_priv = catchall->elem;
9327+
if (sync) {
9328+
struct nft_set_elem elem = {
9329+
.priv = elem_priv,
9330+
};
9331+
9332+
nft_setelem_data_deactivate(gc->net, gc->set, &elem);
9333+
nft_setelem_catchall_destroy(catchall);
9334+
}
9335+
9336+
nft_trans_gc_elem_add(gc, elem_priv);
93219337
}
93229338

93239339
return gc;

0 commit comments

Comments
 (0)