diff options
| author | Inseo An <y0un9sa@gmail.com> | 2026-02-17 21:14:40 +0900 |
|---|---|---|
| committer | Sasha Levin <sashal@kernel.org> | 2026-03-04 07:20:06 -0500 |
| commit | 2a6586ecfa4ce1413daaafee250d2590e05f1a33 (patch) | |
| tree | beafc0bad52e62be2b4356a6af4e0b6d47bf536f /net | |
| parent | dcf9b3c90e5560339649d088836529883fb509f3 (diff) | |
netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ]
nf_tables_addchain() publishes the chain to table->chains via
list_add_tail_rcu() (in nft_chain_add()) before registering hooks.
If nf_tables_register_hook() then fails, the error path calls
nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy()
with no RCU grace period in between.
This creates two use-after-free conditions:
1) Control-plane: nf_tables_dump_chains() traverses table->chains
under rcu_read_lock(). A concurrent dump can still be walking
the chain when the error path frees it.
2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly
installs the IPv4 hook before IPv6 registration fails. Packets
entering nft_do_chain() via the transient IPv4 hook can still be
dereferencing chain->blob_gen_X when the error path frees the
chain.
Add synchronize_rcu() between nft_chain_del() and the chain destroy
so that all RCU readers -- both dump threads and in-flight packet
evaluation -- have finished before the chain is freed.
Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain")
Signed-off-by: Inseo An <y0un9sa@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 67729d7c913a..ac3618395651 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2510,6 +2510,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, err_register_hook: nft_chain_del(chain); + synchronize_rcu(); err_chain_add: nft_trans_destroy(trans); err_trans: |
