diff options
author | Quan Tian <tianquan23@gmail.com> | 2024-03-07 01:24:02 +0800 |
---|---|---|
committer | Sasha Levin <sashal@kernel.org> | 2024-03-26 18:18:59 -0400 |
commit | 4e4623a4f6e133e671f65f9ac493bddaaf63e250 (patch) | |
tree | 29fddad3b3ea606634763f7e389e08744d995c8a /net | |
parent | 840798563f29f65e904298354ed9e2747f2142ee (diff) | |
download | linux-stable-4e4623a4f6e133e671f65f9ac493bddaaf63e250.tar.gz linux-stable-4e4623a4f6e133e671f65f9ac493bddaaf63e250.tar.bz2 linux-stable-4e4623a4f6e133e671f65f9ac493bddaaf63e250.zip |
netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
[ Upstream commit 7eaf837a4eb5f74561e2486972e7f5184b613f6e ]
If nft_netdev_register_hooks() fails, the memory associated with
nft_stats is not freed, causing a memory leak.
This patch fixes it by moving nft_stats_alloc() down after
nft_netdev_register_hooks() succeeds.
Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
Signed-off-by: Quan Tian <tianquan23@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_tables_api.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 85d9e1394330..0130c2782cdc 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2619,19 +2619,6 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy, } } - if (nla[NFTA_CHAIN_COUNTERS]) { - if (!nft_is_base_chain(chain)) { - err = -EOPNOTSUPP; - goto err_hooks; - } - - stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]); - if (IS_ERR(stats)) { - err = PTR_ERR(stats); - goto err_hooks; - } - } - if (!(table->flags & NFT_TABLE_F_DORMANT) && nft_is_base_chain(chain) && !list_empty(&hook.list)) { @@ -2646,6 +2633,20 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy, } unregister = true; + + if (nla[NFTA_CHAIN_COUNTERS]) { + if (!nft_is_base_chain(chain)) { + err = -EOPNOTSUPP; + goto err_hooks; + } + + stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]); + if (IS_ERR(stats)) { + err = PTR_ERR(stats); + goto err_hooks; + } + } + err = -ENOMEM; trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN, sizeof(struct nft_trans_chain)); |