Skip to content

Commit

Permalink
netfilter: nf_tables: fix memleak when more than 255 elements expired
Browse files Browse the repository at this point in the history
jira VUlN-597
cve CVE-2023-52581
commit-author Florian Westphal <[email protected]>
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 <[email protected]>
	Signed-off-by: Florian Westphal <[email protected]>
(cherry picked from commit cf5000a)
	Signed-off-by: Greg Rose <[email protected]>
  • Loading branch information
gvrose8192 committed Oct 30, 2024
1 parent f915f20 commit a75d8c6
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
2 changes: 1 addition & 1 deletion include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ struct nft_trans_gc {
struct net *net;
struct nft_set *set;
u32 seq;
u8 count;
u16 count;
void *priv[NFT_TRANS_GC_BATCHCOUNT];
struct rcu_head rcu;
};
Expand Down
10 changes: 8 additions & 2 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -7955,12 +7955,15 @@ static int nft_trans_gc_space(struct nft_trans_gc *trans)
struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
unsigned int gc_seq, gfp_t gfp)
{
struct nft_set *set;

if (nft_trans_gc_space(gc))
return gc;

set = gc->set;
nft_trans_gc_queue_work(gc);

return nft_trans_gc_alloc(gc->set, gc_seq, gfp);
return nft_trans_gc_alloc(set, gc_seq, gfp);
}
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_async);

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

struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp)
{
struct nft_set *set;

if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)))
return NULL;

if (nft_trans_gc_space(gc))
return gc;

set = gc->set;
call_rcu(&gc->rcu, nft_trans_gc_trans_free);

return nft_trans_gc_alloc(gc->set, 0, gfp);
return nft_trans_gc_alloc(set, 0, gfp);
}
EXPORT_SYMBOL_GPL(nft_trans_gc_queue_sync);

Expand Down

0 comments on commit a75d8c6

Please sign in to comment.