diff mbox series

[nf-next] netfilter: nat: switch release of ops to kfree_rcu

Message ID 20260410114144.10785-1-fw@strlen.de
State Changes Requested
Headers show
Series [nf-next] netfilter: nat: switch release of ops to kfree_rcu | expand

Commit Message

Florian Westphal April 10, 2026, 11:41 a.m. UTC
Historically this is't an issue, even for normal base hooks: the data
path doesn't use the original nf_hook_ops that are used to register
the callbacks.

However, in v5.14 I added the ability to dump the active netfilter
hooks from userspace.

This code will peek back into the nf_hook_ops that are available
at the tail of the pointer-array blob used by the datapath.

The nat hooks are special, because they are called indirectly from
the central nat dispatcher hook.  They are currently invisible to
the nfnl hook dump subsystem.

But once that changes the nat ops structures have to be deferred too.

Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 @pablo: route via nf if you prefer, in that case you can
 add:
  Fixes: e2cf17d3774c ("netfilter: add new hook nfnl subsystem")

 But as explained above, I don't think its a problem for current
 nf/net; the nat hooks are currently not dumpable from nfnl_hook.

 net/ipv4/netfilter/iptable_nat.c  | 2 +-
 net/ipv6/netfilter/ip6table_nat.c | 2 +-
 net/netfilter/nf_nat_core.c       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index a5db7c67d61b..3b1de7f82bf8 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -100,7 +100,7 @@  static void ipt_nat_unregister_lookups(struct net *net)
 	for (i = 0; i < ARRAY_SIZE(nf_nat_ipv4_ops); i++)
 		nf_nat_ipv4_unregister_fn(net, &ops[i]);
 
-	kfree(ops);
+	kfree_rcu(ops, rcu);
 }
 
 static int iptable_nat_table_init(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index e119d4f090cc..9adfbfeaab0c 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -102,7 +102,7 @@  static void ip6t_nat_unregister_lookups(struct net *net)
 	for (i = 0; i < ARRAY_SIZE(nf_nat_ipv6_ops); i++)
 		nf_nat_ipv6_unregister_fn(net, &ops[i]);
 
-	kfree(ops);
+	kfree_rcu(ops, rcu);
 }
 
 static int ip6table_nat_table_init(struct net *net)
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 3b5434e4ec9c..e8beefa503e5 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -1294,7 +1294,7 @@  void nf_nat_unregister_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops,
 		}
 
 		nat_proto_net->nat_hook_ops = NULL;
-		kfree(nat_ops);
+		kfree_rcu(nat_ops, rcu);
 	}
 unlock:
 	mutex_unlock(&nf_nat_proto_mutex);