diff mbox series

[6.1,1/2] netfilter: nf_tables: allow to create netdev chain without device

Message ID tencent_3EF2E566E214C1068698C581DE374E1E3C09@qq.com
State New
Headers show
Series [6.1,1/2] netfilter: nf_tables: allow to create netdev chain without device | expand

Commit Message

Ma Xinmeng Oct. 2, 2026, 4:25 a.m. UTC
From: Pablo Neira Ayuso <pablo@netfilter.org>

Relax netdev chain creation to allow for loading the ruleset, then
adding/deleting devices at a later stage. Hardware offload does not
support for this feature yet.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Ma Xinmeng <1564938642@qq.com>

This is a 6.1 backport of upstream commit 207296f1a03b; the hunk for
nft_delchain_hook() is dropped since that function is not present in 6.1.
---
 net/netfilter/nf_tables_api.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

Comments

Sasha Levin Oct. 2, 2026, 9:10 p.m. UTC | #1
> This is a 6.1 backport of upstream commit 207296f1a03b; the hunk for
> nft_delchain_hook() is dropped since that function is not present in 6.1.

This series only brings in the prerequisites. The UAF fix itself isn't
in it:

  fc0133428e7a ("netfilter: nf_tables: Tolerate chains with no remaining hooks")
  375f222800bc ("netfilter: nf_tables: Simplify chain netdev notifier")

2/2 also adds b9703ed44ffb ("netfilter: nf_tables: support for adding
new devices to an existing netdev chain") to 6.1 without the later
fixes for it, none of which 6.1 has:

  043d2acf5722 ("netfilter: nf_tables: drop module reference after updating chain")
  7eaf837a4eb5 ("netfilter: nf_tables: Fix a memory leak in nf_tables_updchain")
  1e1fb6f00f52 ("netfilter: nf_tables: reject table flag and netdev basechain updates")
  216e7bf7402c ("netfilter: nf_tables: skip netdev hook unregistration if table is dormant")
  688c15017d5c ("netfilter: nf_tables: don't unregister hook when table is dormant")
  4ffcf5ca81c3 ("netfilter: nf_tables: use rcu chain hook list iterator from netlink dump path")

It also needs the netdev chain parts of a6134e62dba2 ("netfilter:
nf_tables: join hook list via splice_list_rcu() in commit phase") and
cf5fb87fcdaa ("netfilter: nf_tables: reject duplicate device on
updates"); 6.1 only has their flowtable parts. Without 043d2acf5722,
every base chain update that carries a hook leaks a reference on the
chain type module.

Could you send a single 6.1 series in upstream order: the two
prerequisites, the fixes above, then fc0133428e7a and 375f222800bc?
Please start each patch with its "commit <sha> upstream." line and add
a cover letter. An ack from Pablo or Florian would help too.

5.15 and 5.10 have the same UAF. Are you planning to cover them as well?
Pablo Neira Ayuso Oct. 2, 2026, 9:44 p.m. UTC | #2
Hi,

On Fri, Oct 02, 2026 at 05:10:34PM -0400, Sasha Levin wrote:
> > This is a 6.1 backport of upstream commit 207296f1a03b; the hunk for
> > nft_delchain_hook() is dropped since that function is not present in 6.1.
> 
> This series only brings in the prerequisites. The UAF fix itself isn't
> in it:
> 
>   fc0133428e7a ("netfilter: nf_tables: Tolerate chains with no remaining hooks")
>   375f222800bc ("netfilter: nf_tables: Simplify chain netdev notifier")
> 
> 2/2 also adds b9703ed44ffb ("netfilter: nf_tables: support for adding
> new devices to an existing netdev chain") to 6.1 without the later
> fixes for it, none of which 6.1 has:
> 
>   043d2acf5722 ("netfilter: nf_tables: drop module reference after updating chain")
>   7eaf837a4eb5 ("netfilter: nf_tables: Fix a memory leak in nf_tables_updchain")
>   1e1fb6f00f52 ("netfilter: nf_tables: reject table flag and netdev basechain updates")
>   216e7bf7402c ("netfilter: nf_tables: skip netdev hook unregistration if table is dormant")
>   688c15017d5c ("netfilter: nf_tables: don't unregister hook when table is dormant")
>   4ffcf5ca81c3 ("netfilter: nf_tables: use rcu chain hook list iterator from netlink dump path")
> 
> It also needs the netdev chain parts of a6134e62dba2 ("netfilter:
> nf_tables: join hook list via splice_list_rcu() in commit phase") and
> cf5fb87fcdaa ("netfilter: nf_tables: reject duplicate device on
> updates"); 6.1 only has their flowtable parts. Without 043d2acf5722,
> every base chain update that carries a hook leaks a reference on the
> chain type module.
> 
> Could you send a single 6.1 series in upstream order: the two
> prerequisites, the fixes above, then fc0133428e7a and 375f222800bc?
> Please start each patch with its "commit <sha> upstream." line and add
> a cover letter. An ack from Pablo or Florian would help too.
> 
> 5.15 and 5.10 have the same UAF. Are you planning to cover them as well?

Yes, I am collecting backport patches and preparing a batch for you.
diff mbox series

Patch

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 96b0638c2..18aa388d5 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2180,7 +2180,7 @@  struct nft_chain_hook {
 
 static int nft_chain_parse_netdev(struct net *net,
 				  struct nlattr *tb[],
-				  struct list_head *hook_list)
+				  struct list_head *hook_list, u32 flags)
 {
 	struct nft_hook *hook;
 	int err;
@@ -2197,19 +2197,20 @@  static int nft_chain_parse_netdev(struct net *net,
 		if (err < 0)
 			return err;
 
-		if (list_empty(hook_list))
-			return -EINVAL;
-	} else {
-		return -EINVAL;
 	}
 
+	if (flags & NFT_CHAIN_HW_OFFLOAD &&
+	    list_empty(hook_list))
+		return -EINVAL;
+
 	return 0;
 }
 
 static int nft_chain_parse_hook(struct net *net,
 				const struct nlattr * const nla[],
 				struct nft_chain_hook *hook, u8 family,
-				struct netlink_ext_ack *extack, bool autoload)
+				struct netlink_ext_ack *extack, bool autoload,
+				u32 flags)
 {
 	struct nftables_pernet *nft_net = nft_pernet(net);
 	struct nlattr *ha[NFTA_HOOK_MAX + 1];
@@ -2261,7 +2262,7 @@  static int nft_chain_parse_hook(struct net *net,
 
 	INIT_LIST_HEAD(&hook->list);
 	if (nft_base_chain_netdev(family, hook->num)) {
-		err = nft_chain_parse_netdev(net, ha, &hook->list);
+		err = nft_chain_parse_netdev(net, ha, &hook->list, flags);
 		if (err < 0) {
 			module_put(type->owner);
 			return err;
@@ -2409,7 +2410,7 @@  static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 			return -EOPNOTSUPP;
 
 		err = nft_chain_parse_hook(net, nla, &hook, family, extack,
-					   true);
+					   true, flags);
 		if (err < 0)
 			return err;
 
@@ -2574,7 +2575,7 @@  static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
 			return -EEXIST;
 		}
 		err = nft_chain_parse_hook(ctx->net, nla, &hook, ctx->family,
-					   extack, false);
+					   extack, false, flags);
 		if (err < 0)
 			return err;
 
@@ -2795,6 +2796,7 @@  static int nf_tables_newchain(struct sk_buff *skb, const struct nfnl_info *info,
 	return nf_tables_addchain(&ctx, family, genmask, policy, flags, extack);
 }
 
+
 static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info,
 			      const struct nlattr * const nla[])
 {