public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH -stable,6.1 0/3] Netfilter fixes for -stable
@ 2025-05-19 23:34 Pablo Neira Ayuso
  2025-05-19 23:34 ` [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx Pablo Neira Ayuso
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2025-05-19 23:34 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

Hi Greg, Sasha,

This batch contains backported fixes for 6.1 -stable.

The following list shows the backported patches, I am using original commit
IDs for reference:

1) 8965d42bcf54 ("netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx")

   This is a stable dependency for the next patch.

2) c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal")

3) b04df3da1b5c ("netfilter: nf_tables: do not defer rule destruction via call_rcu")

   This is a fix-for-fix for patch 2.

These three patches are required to fix the netdevice release path for
netdev family basechains.

Please, apply,
Thanks

Florian Westphal (2):
  netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
  netfilter: nf_tables: do not defer rule destruction via call_rcu

Pablo Neira Ayuso (1):
  netfilter: nf_tables: wait for rcu grace period on net_device removal

 include/net/netfilter/nf_tables.h |  3 +-
 net/netfilter/nf_tables_api.c     | 54 ++++++++++++++++++++++---------
 net/netfilter/nft_immediate.c     |  2 +-
 3 files changed, 42 insertions(+), 17 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
  2025-05-19 23:34 [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Pablo Neira Ayuso
@ 2025-05-19 23:34 ` Pablo Neira Ayuso
  2025-05-20 13:42   ` Sasha Levin
  2025-05-19 23:34 ` [PATCH -stable,6.1 2/3] netfilter: nf_tables: wait for rcu grace period on net_device removal Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Pablo Neira Ayuso @ 2025-05-19 23:34 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

From: Florian Westphal <fw@strlen.de>

commit 8965d42bcf54d42cbc72fe34a9d0ec3f8527debd upstream.

It would be better to not store nft_ctx inside nft_trans object,
the netlink ctx strucutre is huge and most of its information is
never needed in places that use trans->ctx.

Avoid/reduce its usage if possible, no runtime behaviour change
intended.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Stable-dep-of: c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/netfilter/nf_tables.h |  2 +-
 net/netfilter/nf_tables_api.c     | 17 ++++++++---------
 net/netfilter/nft_immediate.c     |  2 +-
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index d11398aa642e..41abb5982348 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1121,7 +1121,7 @@ static inline bool nft_chain_is_bound(struct nft_chain *chain)
 
 int nft_chain_add(struct nft_table *table, struct nft_chain *chain);
 void nft_chain_del(struct nft_chain *chain);
-void nf_tables_chain_destroy(struct nft_ctx *ctx);
+void nf_tables_chain_destroy(struct nft_chain *chain);
 
 struct nft_stats {
 	u64			bytes;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 656c4fb76773..dc1e11c0b168 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2034,9 +2034,9 @@ static void nf_tables_chain_free_chain_rules(struct nft_chain *chain)
 	kvfree(chain->blob_next);
 }
 
-void nf_tables_chain_destroy(struct nft_ctx *ctx)
+void nf_tables_chain_destroy(struct nft_chain *chain)
 {
-	struct nft_chain *chain = ctx->chain;
+	const struct nft_table *table = chain->table;
 	struct nft_hook *hook, *next;
 
 	if (WARN_ON(chain->use > 0))
@@ -2048,7 +2048,7 @@ void nf_tables_chain_destroy(struct nft_ctx *ctx)
 	if (nft_is_base_chain(chain)) {
 		struct nft_base_chain *basechain = nft_base_chain(chain);
 
-		if (nft_base_chain_netdev(ctx->family, basechain->ops.hooknum)) {
+		if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) {
 			list_for_each_entry_safe(hook, next,
 						 &basechain->hook_list, list) {
 				list_del_rcu(&hook->list);
@@ -2515,7 +2515,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 err_trans:
 	nft_use_dec_restore(&table->use);
 err_destroy_chain:
-	nf_tables_chain_destroy(ctx);
+	nf_tables_chain_destroy(chain);
 
 	return err;
 }
@@ -8994,7 +8994,7 @@ static void nft_commit_release(struct nft_trans *trans)
 		kfree(nft_trans_chain_name(trans));
 		break;
 	case NFT_MSG_DELCHAIN:
-		nf_tables_chain_destroy(&trans->ctx);
+		nf_tables_chain_destroy(nft_trans_chain(trans));
 		break;
 	case NFT_MSG_DELRULE:
 		nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
@@ -9955,7 +9955,7 @@ static void nf_tables_abort_release(struct nft_trans *trans)
 		nf_tables_table_destroy(&trans->ctx);
 		break;
 	case NFT_MSG_NEWCHAIN:
-		nf_tables_chain_destroy(&trans->ctx);
+		nf_tables_chain_destroy(nft_trans_chain(trans));
 		break;
 	case NFT_MSG_NEWRULE:
 		nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
@@ -10677,7 +10677,7 @@ int __nft_release_basechain(struct nft_ctx *ctx)
 	}
 	nft_chain_del(ctx->chain);
 	nft_use_dec(&ctx->table->use);
-	nf_tables_chain_destroy(ctx);
+	nf_tables_chain_destroy(ctx->chain);
 
 	return 0;
 }
@@ -10753,10 +10753,9 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
 		nft_obj_destroy(&ctx, obj);
 	}
 	list_for_each_entry_safe(chain, nc, &table->chains, list) {
-		ctx.chain = chain;
 		nft_chain_del(chain);
 		nft_use_dec(&table->use);
-		nf_tables_chain_destroy(&ctx);
+		nf_tables_chain_destroy(chain);
 	}
 	nf_tables_table_destroy(&ctx);
 }
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 55fcf0280c5c..731511d58b7c 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -221,7 +221,7 @@ static void nft_immediate_destroy(const struct nft_ctx *ctx,
 			list_del(&rule->list);
 			nf_tables_rule_destroy(&chain_ctx, rule);
 		}
-		nf_tables_chain_destroy(&chain_ctx);
+		nf_tables_chain_destroy(chain);
 		break;
 	default:
 		break;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH -stable,6.1 2/3] netfilter: nf_tables: wait for rcu grace period on net_device removal
  2025-05-19 23:34 [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Pablo Neira Ayuso
  2025-05-19 23:34 ` [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx Pablo Neira Ayuso
@ 2025-05-19 23:34 ` Pablo Neira Ayuso
  2025-05-20 13:36   ` Sasha Levin
  2025-05-19 23:34 ` [PATCH -stable,6.1 3/3] netfilter: nf_tables: do not defer rule destruction via call_rcu Pablo Neira Ayuso
  2025-05-20 11:09 ` [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Greg KH
  3 siblings, 1 reply; 8+ messages in thread
From: Pablo Neira Ayuso @ 2025-05-19 23:34 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

commit c03d278fdf35e73dd0ec543b9b556876b9d9a8dc upstream.

8c873e219970 ("netfilter: core: free hooks with call_rcu") removed
synchronize_net() call when unregistering basechain hook, however,
net_device removal event handler for the NFPROTO_NETDEV was not updated
to wait for RCU grace period.

Note that 835b803377f5 ("netfilter: nf_tables_netdev: unregister hooks
on net_device removal") does not remove basechain rules on device
removal, I was hinted to remove rules on net_device removal later, see
5ebe0b0eec9d ("netfilter: nf_tables: destroy basechain and rules on
netdevice removal").

Although NETDEV_UNREGISTER event is guaranteed to be handled after
synchronize_net() call, this path needs to wait for rcu grace period via
rcu callback to release basechain hooks if netns is alive because an
ongoing netlink dump could be in progress (sockets hold a reference on
the netns).

Note that nf_tables_pre_exit_net() unregisters and releases basechain
hooks but it is possible to see NETDEV_UNREGISTER at a later stage in
the netns exit path, eg. veth peer device in another netns:

 cleanup_net()
  default_device_exit_batch()
   unregister_netdevice_many_notify()
    notifier_call_chain()
     nf_tables_netdev_event()
      __nft_release_basechain()

In this particular case, same rule of thumb applies: if netns is alive,
then wait for rcu grace period because netlink dump in the other netns
could be in progress. Otherwise, if the other netns is going away then
no netlink dump can be in progress and basechain hooks can be released
inmediately.

While at it, turn WARN_ON() into WARN_ON_ONCE() for the basechain
validation, which should not ever happen.

Fixes: 835b803377f5 ("netfilter: nf_tables_netdev: unregister hooks on net_device removal")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h |  4 +++
 net/netfilter/nf_tables_api.c     | 41 +++++++++++++++++++++++++------
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 41abb5982348..76a51ed432ca 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1045,6 +1045,7 @@ struct nft_rule_blob {
  *	@use: number of jump references to this chain
  *	@flags: bitmask of enum nft_chain_flags
  *	@name: name of the chain
+ *	@rcu_head: rcu head for deferred release
  */
 struct nft_chain {
 	struct nft_rule_blob		__rcu *blob_gen_0;
@@ -1061,6 +1062,7 @@ struct nft_chain {
 	char				*name;
 	u16				udlen;
 	u8				*udata;
+	struct rcu_head			rcu_head;
 
 	/* Only used during control plane commit phase: */
 	struct nft_rule_blob		*blob_next;
@@ -1203,6 +1205,7 @@ static inline void nft_use_inc_restore(u32 *use)
  *	@sets: sets in the table
  *	@objects: stateful objects in the table
  *	@flowtables: flow tables in the table
+ *	@net: netnamespace this table belongs to
  *	@hgenerator: handle generator state
  *	@handle: table handle
  *	@use: number of chain references to this table
@@ -1218,6 +1221,7 @@ struct nft_table {
 	struct list_head		sets;
 	struct list_head		objects;
 	struct list_head		flowtables;
+	possible_net_t			net;
 	u64				hgenerator;
 	u64				handle;
 	u32				use;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index dc1e11c0b168..aa1a85eff61b 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1413,6 +1413,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
 	INIT_LIST_HEAD(&table->sets);
 	INIT_LIST_HEAD(&table->objects);
 	INIT_LIST_HEAD(&table->flowtables);
+	write_pnet(&table->net, net);
 	table->family = family;
 	table->flags = flags;
 	table->handle = ++nft_net->table_handle;
@@ -10662,22 +10663,48 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
 }
 EXPORT_SYMBOL_GPL(nft_data_dump);
 
-int __nft_release_basechain(struct nft_ctx *ctx)
+static void __nft_release_basechain_now(struct nft_ctx *ctx)
 {
 	struct nft_rule *rule, *nr;
 
-	if (WARN_ON(!nft_is_base_chain(ctx->chain)))
-		return 0;
-
-	nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
 	list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
 		list_del(&rule->list);
-		nft_use_dec(&ctx->chain->use);
 		nf_tables_rule_release(ctx, rule);
 	}
+	nf_tables_chain_destroy(ctx->chain);
+}
+
+static void nft_release_basechain_rcu(struct rcu_head *head)
+{
+	struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
+	struct nft_ctx ctx = {
+		.family	= chain->table->family,
+		.chain	= chain,
+		.net	= read_pnet(&chain->table->net),
+	};
+
+	__nft_release_basechain_now(&ctx);
+	put_net(ctx.net);
+}
+
+int __nft_release_basechain(struct nft_ctx *ctx)
+{
+	struct nft_rule *rule;
+
+	if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
+		return 0;
+
+	nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
+	list_for_each_entry(rule, &ctx->chain->rules, list)
+		nft_use_dec(&ctx->chain->use);
+
 	nft_chain_del(ctx->chain);
 	nft_use_dec(&ctx->table->use);
-	nf_tables_chain_destroy(ctx->chain);
+
+	if (maybe_get_net(ctx->net))
+		call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu);
+	else
+		__nft_release_basechain_now(ctx);
 
 	return 0;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH -stable,6.1 3/3] netfilter: nf_tables: do not defer rule destruction via call_rcu
  2025-05-19 23:34 [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Pablo Neira Ayuso
  2025-05-19 23:34 ` [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx Pablo Neira Ayuso
  2025-05-19 23:34 ` [PATCH -stable,6.1 2/3] netfilter: nf_tables: wait for rcu grace period on net_device removal Pablo Neira Ayuso
@ 2025-05-19 23:34 ` Pablo Neira Ayuso
  2025-05-20 13:40   ` Sasha Levin
  2025-05-20 11:09 ` [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Greg KH
  3 siblings, 1 reply; 8+ messages in thread
From: Pablo Neira Ayuso @ 2025-05-19 23:34 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

From: Florian Westphal <fw@strlen.de>

commit b04df3da1b5c6f6dc7cdccc37941740c078c4043 upstream.

nf_tables_chain_destroy can sleep, it can't be used from call_rcu
callbacks.

Moreover, nf_tables_rule_release() is only safe for error unwinding,
while transaction mutex is held and the to-be-desroyed rule was not
exposed to either dataplane or dumps, as it deactives+frees without
the required synchronize_rcu() in-between.

nft_rule_expr_deactivate() callbacks will change ->use counters
of other chains/sets, see e.g. nft_lookup .deactivate callback, these
must be serialized via transaction mutex.

Also add a few lockdep asserts to make this more explicit.

Calling synchronize_rcu() isn't ideal, but fixing this without is hard
and way more intrusive.  As-is, we can get:

WARNING: .. net/netfilter/nf_tables_api.c:5515 nft_set_destroy+0x..
Workqueue: events nf_tables_trans_destroy_work
RIP: 0010:nft_set_destroy+0x3fe/0x5c0
Call Trace:
 <TASK>
 nf_tables_trans_destroy_work+0x6b7/0xad0
 process_one_work+0x64a/0xce0
 worker_thread+0x613/0x10d0

In case the synchronize_rcu becomes an issue, we can explore alternatives.

One way would be to allocate nft_trans_rule objects + one nft_trans_chain
object, deactivate the rules + the chain and then defer the freeing to the
nft destroy workqueue.  We'd still need to keep the synchronize_rcu path as
a fallback to handle -ENOMEM corner cases though.

Reported-by: syzbot+b26935466701e56cfdc2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/67478d92.050a0220.253251.0062.GAE@google.com/T/
Fixes: c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h |  3 ---
 net/netfilter/nf_tables_api.c     | 32 +++++++++++++++----------------
 2 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 76a51ed432ca..7252a5aae069 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1062,7 +1062,6 @@ struct nft_chain {
 	char				*name;
 	u16				udlen;
 	u8				*udata;
-	struct rcu_head			rcu_head;
 
 	/* Only used during control plane commit phase: */
 	struct nft_rule_blob		*blob_next;
@@ -1205,7 +1204,6 @@ static inline void nft_use_inc_restore(u32 *use)
  *	@sets: sets in the table
  *	@objects: stateful objects in the table
  *	@flowtables: flow tables in the table
- *	@net: netnamespace this table belongs to
  *	@hgenerator: handle generator state
  *	@handle: table handle
  *	@use: number of chain references to this table
@@ -1221,7 +1219,6 @@ struct nft_table {
 	struct list_head		sets;
 	struct list_head		objects;
 	struct list_head		flowtables;
-	possible_net_t			net;
 	u64				hgenerator;
 	u64				handle;
 	u32				use;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index aa1a85eff61b..0bf347a0a1dd 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1413,7 +1413,6 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
 	INIT_LIST_HEAD(&table->sets);
 	INIT_LIST_HEAD(&table->objects);
 	INIT_LIST_HEAD(&table->flowtables);
-	write_pnet(&table->net, net);
 	table->family = family;
 	table->flags = flags;
 	table->handle = ++nft_net->table_handle;
@@ -3511,8 +3510,11 @@ void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule)
 	kfree(rule);
 }
 
+/* can only be used if rule is no longer visible to dumps */
 static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
 {
+	lockdep_commit_lock_is_held(ctx->net);
+
 	nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
 	nf_tables_rule_destroy(ctx, rule);
 }
@@ -5248,6 +5250,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
 			      struct nft_set_binding *binding,
 			      enum nft_trans_phase phase)
 {
+	lockdep_commit_lock_is_held(ctx->net);
+
 	switch (phase) {
 	case NFT_TRANS_PREPARE_ERROR:
 		nft_set_trans_unbind(ctx, set);
@@ -10674,19 +10678,6 @@ static void __nft_release_basechain_now(struct nft_ctx *ctx)
 	nf_tables_chain_destroy(ctx->chain);
 }
 
-static void nft_release_basechain_rcu(struct rcu_head *head)
-{
-	struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
-	struct nft_ctx ctx = {
-		.family	= chain->table->family,
-		.chain	= chain,
-		.net	= read_pnet(&chain->table->net),
-	};
-
-	__nft_release_basechain_now(&ctx);
-	put_net(ctx.net);
-}
-
 int __nft_release_basechain(struct nft_ctx *ctx)
 {
 	struct nft_rule *rule;
@@ -10701,11 +10692,18 @@ int __nft_release_basechain(struct nft_ctx *ctx)
 	nft_chain_del(ctx->chain);
 	nft_use_dec(&ctx->table->use);
 
-	if (maybe_get_net(ctx->net))
-		call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu);
-	else
+	if (!maybe_get_net(ctx->net)) {
 		__nft_release_basechain_now(ctx);
+		return 0;
+	}
+
+	/* wait for ruleset dumps to complete.  Owning chain is no longer in
+	 * lists, so new dumps can't find any of these rules anymore.
+	 */
+	synchronize_rcu();
 
+	__nft_release_basechain_now(ctx);
+	put_net(ctx->net);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(__nft_release_basechain);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH -stable,6.1 0/3] Netfilter fixes for -stable
  2025-05-19 23:34 [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2025-05-19 23:34 ` [PATCH -stable,6.1 3/3] netfilter: nf_tables: do not defer rule destruction via call_rcu Pablo Neira Ayuso
@ 2025-05-20 11:09 ` Greg KH
  3 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2025-05-20 11:09 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, sashal, stable

On Tue, May 20, 2025 at 01:34:35AM +0200, Pablo Neira Ayuso wrote:
> Hi Greg, Sasha,
> 
> This batch contains backported fixes for 6.1 -stable.
> 
> The following list shows the backported patches, I am using original commit
> IDs for reference:
> 
> 1) 8965d42bcf54 ("netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx")
> 
>    This is a stable dependency for the next patch.
> 
> 2) c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal")
> 
> 3) b04df3da1b5c ("netfilter: nf_tables: do not defer rule destruction via call_rcu")
> 
>    This is a fix-for-fix for patch 2.
> 
> These three patches are required to fix the netdevice release path for
> netdev family basechains.
> 

All now queued up, thanks!

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH -stable,6.1 2/3] netfilter: nf_tables: wait for rcu grace period on net_device removal
  2025-05-19 23:34 ` [PATCH -stable,6.1 2/3] netfilter: nf_tables: wait for rcu grace period on net_device removal Pablo Neira Ayuso
@ 2025-05-20 13:36   ` Sasha Levin
  0 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2025-05-20 13:36 UTC (permalink / raw)
  To: stable, pablo; +Cc: Sasha Levin

[ Sasha's backport helper bot ]

Hi,

Summary of potential issues:
ℹ️ This is part 2/3 of a series
⚠️ Found follow-up fixes in mainline

The upstream commit SHA1 provided is correct: c03d278fdf35e73dd0ec543b9b556876b9d9a8dc

Status in newer kernel trees:
6.14.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: bfd05c68e4c6)

Found fixes commits:
b04df3da1b5c netfilter: nf_tables: do not defer rule destruction via call_rcu

Note: The patch differs from the upstream commit:
---
1:  c03d278fdf35e ! 1:  d6fc62cb7e09f netfilter: nf_tables: wait for rcu grace period on net_device removal
    @@ Metadata
      ## Commit message ##
         netfilter: nf_tables: wait for rcu grace period on net_device removal
     
    +    commit c03d278fdf35e73dd0ec543b9b556876b9d9a8dc upstream.
    +
         8c873e219970 ("netfilter: core: free hooks with call_rcu") removed
         synchronize_net() call when unregistering basechain hook, however,
         net_device removal event handler for the NFPROTO_NETDEV was not updated
    @@ Commit message
     
      ## include/net/netfilter/nf_tables.h ##
     @@ include/net/netfilter/nf_tables.h: struct nft_rule_blob {
    +  *	@use: number of jump references to this chain
    +  *	@flags: bitmask of enum nft_chain_flags
       *	@name: name of the chain
    -  *	@udlen: user data length
    -  *	@udata: user data in the chain
     + *	@rcu_head: rcu head for deferred release
    -  *	@blob_next: rule blob pointer to the next in the chain
       */
      struct nft_chain {
    + 	struct nft_rule_blob		__rcu *blob_gen_0;
     @@ include/net/netfilter/nf_tables.h: struct nft_chain {
      	char				*name;
      	u16				udlen;
---

NOTE: These results are for this patch alone. Full series testing will be
performed when all parts are received.

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.6.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH -stable,6.1 3/3] netfilter: nf_tables: do not defer rule destruction via call_rcu
  2025-05-19 23:34 ` [PATCH -stable,6.1 3/3] netfilter: nf_tables: do not defer rule destruction via call_rcu Pablo Neira Ayuso
@ 2025-05-20 13:40   ` Sasha Levin
  0 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2025-05-20 13:40 UTC (permalink / raw)
  To: stable; +Cc: Pablo Neira Ayuso, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

✅ All tests passed successfully. No issues detected.
No action required from the submitter.

The upstream commit SHA1 provided is correct: b04df3da1b5c6f6dc7cdccc37941740c078c4043

WARNING: Author mismatch between patch and upstream commit:
Backport author: Pablo Neira Ayuso<pablo@netfilter.org>
Commit author: Florian Westphal<fw@strlen.de>

Status in newer kernel trees:
6.14.y | Present (exact SHA1)
6.12.y | Present (different SHA1: 7cf0bd232b56)
6.6.y | Present (different SHA1: 27f0574253f6)

Note: The patch differs from the upstream commit:
---
1:  b04df3da1b5c6 ! 1:  5ecb99b42454b netfilter: nf_tables: do not defer rule destruction via call_rcu
    @@ Metadata
      ## Commit message ##
         netfilter: nf_tables: do not defer rule destruction via call_rcu
     
    +    commit b04df3da1b5c6f6dc7cdccc37941740c078c4043 upstream.
    +
         nf_tables_chain_destroy can sleep, it can't be used from call_rcu
         callbacks.
     
    @@ Commit message
         Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
     
      ## include/net/netfilter/nf_tables.h ##
    -@@ include/net/netfilter/nf_tables.h: struct nft_rule_blob {
    -  *	@name: name of the chain
    -  *	@udlen: user data length
    -  *	@udata: user data in the chain
    -- *	@rcu_head: rcu head for deferred release
    -  *	@blob_next: rule blob pointer to the next in the chain
    -  */
    - struct nft_chain {
     @@ include/net/netfilter/nf_tables.h: struct nft_chain {
      	char				*name;
      	u16				udlen;
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.6.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
  2025-05-19 23:34 ` [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx Pablo Neira Ayuso
@ 2025-05-20 13:42   ` Sasha Levin
  0 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2025-05-20 13:42 UTC (permalink / raw)
  To: stable; +Cc: Pablo Neira Ayuso, Sasha Levin

[ Sasha's backport helper bot ]

Hi,

✅ All tests passed successfully. No issues detected.
No action required from the submitter.

The upstream commit SHA1 provided is correct: 8965d42bcf54d42cbc72fe34a9d0ec3f8527debd

WARNING: Author mismatch between patch and upstream commit:
Backport author: Pablo Neira Ayuso<pablo@netfilter.org>
Commit author: Florian Westphal<fw@strlen.de>

Status in newer kernel trees:
6.14.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: 825a80817cf1)

Note: The patch differs from the upstream commit:
---
1:  8965d42bcf54d ! 1:  ef035fe6fb396 netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
    @@ Metadata
      ## Commit message ##
         netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
     
    +    commit 8965d42bcf54d42cbc72fe34a9d0ec3f8527debd upstream.
    +
         It would be better to not store nft_ctx inside nft_trans object,
         the netlink ctx strucutre is huge and most of its information is
         never needed in places that use trans->ctx.
    @@ Commit message
     
         Signed-off-by: Florian Westphal <fw@strlen.de>
         Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
    +    Stable-dep-of: c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal")
    +    Signed-off-by: Sasha Levin <sashal@kernel.org>
     
      ## include/net/netfilter/nf_tables.h ##
     @@ include/net/netfilter/nf_tables.h: static inline bool nft_chain_is_bound(struct nft_chain *chain)
    @@ net/netfilter/nf_tables_api.c: static int nf_tables_addchain(struct nft_ctx *ctx
      	return err;
      }
     @@ net/netfilter/nf_tables_api.c: static void nft_commit_release(struct nft_trans *trans)
    - 		if (nft_trans_chain_update(trans))
    - 			nft_hooks_destroy(&nft_trans_chain_hooks(trans));
    - 		else
    --			nf_tables_chain_destroy(&trans->ctx);
    -+			nf_tables_chain_destroy(nft_trans_chain(trans));
    + 		kfree(nft_trans_chain_name(trans));
    + 		break;
    + 	case NFT_MSG_DELCHAIN:
    +-		nf_tables_chain_destroy(&trans->ctx);
    ++		nf_tables_chain_destroy(nft_trans_chain(trans));
      		break;
      	case NFT_MSG_DELRULE:
    - 	case NFT_MSG_DESTROYRULE:
    + 		nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
     @@ net/netfilter/nf_tables_api.c: static void nf_tables_abort_release(struct nft_trans *trans)
    - 		if (nft_trans_chain_update(trans))
    - 			nft_hooks_destroy(&nft_trans_chain_hooks(trans));
    - 		else
    --			nf_tables_chain_destroy(&trans->ctx);
    -+			nf_tables_chain_destroy(nft_trans_chain(trans));
    + 		nf_tables_table_destroy(&trans->ctx);
    + 		break;
    + 	case NFT_MSG_NEWCHAIN:
    +-		nf_tables_chain_destroy(&trans->ctx);
    ++		nf_tables_chain_destroy(nft_trans_chain(trans));
      		break;
      	case NFT_MSG_NEWRULE:
      		nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.1.y        |  Success    |  Success   |

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-05-20 13:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-19 23:34 [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Pablo Neira Ayuso
2025-05-19 23:34 ` [PATCH -stable,6.1 1/3] netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx Pablo Neira Ayuso
2025-05-20 13:42   ` Sasha Levin
2025-05-19 23:34 ` [PATCH -stable,6.1 2/3] netfilter: nf_tables: wait for rcu grace period on net_device removal Pablo Neira Ayuso
2025-05-20 13:36   ` Sasha Levin
2025-05-19 23:34 ` [PATCH -stable,6.1 3/3] netfilter: nf_tables: do not defer rule destruction via call_rcu Pablo Neira Ayuso
2025-05-20 13:40   ` Sasha Levin
2025-05-20 11:09 ` [PATCH -stable,6.1 0/3] Netfilter fixes for -stable Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox