FAILED: patch "[PATCH] netfilter: arp_tables: add pre_exit hook for table unregister" failed to apply to 4.14-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d163a925ebbc6eb5b562b0f1d72c7e817aa75c40 Mon Sep 17 00:00:00 2001
From: Florian Westphal <[email protected]>
Date: Wed, 7 Apr 2021 21:43:40 +0200
Subject: [PATCH] netfilter: arp_tables: add pre_exit hook for table unregister
Same problem that also existed in iptables/ip(6)tables, when arptable_filter is removed there is no longer a wait period before the table/ruleset is free'd.
Unregister the hook in pre_exit, then remove the table in the exit function.
This used to work correctly because the old nf_hook_unregister API did unconditional synchronize_net.
The per-net hook unregister function uses call_rcu instead.
include/linux/netfilter_arp/arp_tables.h +3 -2
@@ -52,8 +52,9 @@ extern void *arpt_alloc_initial_table(const struct xt_table *);int arpt_register_table (struct net *net,const struct xt_table *table,const struct arpt_replace *repl,const struct nf_hook_ops *ops,struct xt_table **res); -void arpt_unregister_table (struct net *net,struct xt_table *table, -const struct nf_hook_ops *ops); +void arpt_unregister_table (struct net *net,struct xt_table *table); +void arpt_unregister_table_pre_exit (struct net *net,struct xt_table *table, +const struct nf_hook_ops *ops);extern unsigned int arpt_do_table (struct sk_buff *skb,const struct nf_hook_state *state,struct xt_table *table);
net/ipv4/netfilter/arp_tables.c +7 -2
@@ -1539,10 +1539,15 @@ int arpt_register_table(struct net *net,return ret; } -void arpt_unregister_table (struct net *net,struct xt_table *table, -const struct nf_hook_ops *ops) +void arpt_unregister_table_pre_exit (struct net *net,struct xt_table *table, +const struct nf_hook_ops *ops) {nf_unregister_net_hooks (net, ops,hweight32 (table->valid_hooks)); +} +EXPORT_SYMBOL (arpt_unregister_table_pre_exit); + +void arpt_unregister_table (struct net *net,struct xt_table *table) +{__arpt_unregister_table (net, table); }
net/ipv4/netfilter/arptable_filter.c +9 -1
@@ -56,16 +56,24 @@ static int __net_init arptable_filter_table_init(struct net *net)return err; } +static void __net_exit arptable_filter_net_pre_exit(struct net *net) +{ +if (net->ipv4.arptable_filter) +arpt_unregister_table_pre_exit (net, net->ipv4.arptable_filter, + arpfilter_ops); +} + static void __net_exit arptable_filter_net_exit(struct net *net) {if (!net->ipv4.arptable_filter)return ; -arpt_unregister_table (net, net->ipv4.arptable_filter, arpfilter_ops); +arpt_unregister_table (net, net->ipv4.arptable_filter); net->ipv4.arptable_filter =NULL ; }static struct pernet_operations arptable_filter_net_ops = { .exit = arptable_filter_net_exit, + .pre_exit = arptable_filter_net_pre_exit, };static int __init arptable_filter_init (void )