]> git.itanic.dy.fi Git - linux-stable/commitdiff
netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
authorQuan Tian <tianquan23@gmail.com>
Wed, 6 Mar 2024 17:24:02 +0000 (01:24 +0800)
committerSasha Levin <sashal@kernel.org>
Tue, 26 Mar 2024 22:17:38 +0000 (18:17 -0400)
[ 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>
net/netfilter/nf_tables_api.c

index 0fe2abf27d12f6c80c9acc50faee79a7e924fa8e..6873c9815cd311f4fdc9d3d36f40d78ab15ddbd3 100644 (file)
@@ -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));