]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 15 Apr 2026 15:56:14 +0000 (17:56 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 21 Apr 2026 10:48:44 +0000 (12:48 +0200)
Publish new hooks in the list into the basechain/flowtable using
splice_list_rcu() to ensure netlink dump list traversal via rcu is safe
while concurrent ruleset update is going on.

Fixes: 78d9f48f7f44 ("netfilter: nf_tables: add devices to existing flowtable")
Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c

index 07e1512457650fbbd50f204e28561fc1c5c69138..ae10116af9238ab37b6a0ae97e139b6ac1484407 100644 (file)
@@ -10838,8 +10838,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
                                nft_chain_commit_update(nft_trans_container_chain(trans));
                                nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN,
                                                       &nft_trans_chain_hooks(trans));
-                               list_splice(&nft_trans_chain_hooks(trans),
-                                           &nft_trans_basechain(trans)->hook_list);
+                               list_splice_rcu(&nft_trans_chain_hooks(trans),
+                                               &nft_trans_basechain(trans)->hook_list);
                                /* trans destroyed after rcu grace period */
                        } else {
                                nft_chain_commit_drop_policy(nft_trans_container_chain(trans));
@@ -10968,8 +10968,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
                                                           nft_trans_flowtable(trans),
                                                           &nft_trans_flowtable_hooks(trans),
                                                           NFT_MSG_NEWFLOWTABLE);
-                               list_splice(&nft_trans_flowtable_hooks(trans),
-                                           &nft_trans_flowtable(trans)->hook_list);
+                               list_splice_rcu(&nft_trans_flowtable_hooks(trans),
+                                               &nft_trans_flowtable(trans)->hook_list);
                        } else {
                                nft_clear(net, nft_trans_flowtable(trans));
                                nf_tables_flowtable_notify(&ctx,