Skip to content

Commit a75d8c6

Browse files
committed
netfilter: nf_tables: fix memleak when more than 255 elements expired
jira VUlN-597 cve CVE-2023-52581 commit-author Florian Westphal <fw@strlen.de> commit cf5000a upstream-diff some cruft around GPL symbol exports When more than 255 elements expired we're supposed to switch to a new gc container structure. This never happens: u8 type will wrap before reaching the boundary and nft_trans_gc_space() always returns true. This means we recycle the initial gc container structure and lose track of the elements that came before. While at it, don't deref 'gc' after we've passed it to call_rcu. Fixes: 5f68718 ("netfilter: nf_tables: GC transaction API to avoid race with control plane") Reported-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de> (cherry picked from commit cf5000a) Signed-off-by: Greg Rose <g.v.rose@ciq.com>
1 parent f915f20 commit a75d8c6

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ struct nft_trans_gc {
14941494
struct net *net;
14951495
struct nft_set *set;
14961496
u32 seq;
1497-
u8 count;
1497+
u16 count;
14981498
void *priv[NFT_TRANS_GC_BATCHCOUNT];
14991499
struct rcu_head rcu;
15001500
};

net/netfilter/nf_tables_api.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7955,12 +7955,15 @@ static int nft_trans_gc_space(struct nft_trans_gc *trans)
79557955
struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
79567956
unsigned int gc_seq, gfp_t gfp)
79577957
{
7958+
struct nft_set *set;
7959+
79587960
if (nft_trans_gc_space(gc))
79597961
return gc;
79607962

7963+
set = gc->set;
79617964
nft_trans_gc_queue_work(gc);
79627965

7963-
return nft_trans_gc_alloc(gc->set, gc_seq, gfp);
7966+
return nft_trans_gc_alloc(set, gc_seq, gfp);
79647967
}
79657968
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_async);
79667969

@@ -7977,15 +7980,18 @@ EXPORT_SYMBOL_GPL(nft_trans_gc_queue_async_done);
79777980

79787981
struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp)
79797982
{
7983+
struct nft_set *set;
7984+
79807985
if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)))
79817986
return NULL;
79827987

79837988
if (nft_trans_gc_space(gc))
79847989
return gc;
79857990

7991+
set = gc->set;
79867992
call_rcu(&gc->rcu, nft_trans_gc_trans_free);
79877993

7988-
return nft_trans_gc_alloc(gc->set, 0, gfp);
7994+
return nft_trans_gc_alloc(set, 0, gfp);
79897995
}
79907996
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_sync);
79917997

0 commit comments

Comments
 (0)