diff options
author | Vitaly E. Lavrov <lve@guap.ru> | 2012-12-24 08:42:17 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-12-26 12:14:48 -0500 |
commit | 32263dd1b43378b4f7d7796ed713f77e95f27e8a (patch) | |
tree | d730ddc702dcee5ac6888b4b548f970ec68cb1bc /net | |
parent | 665e205c16c1f902ac6763b8ce8a0a3a1dcefe59 (diff) |
netfilter: xt_hashlimit: fix namespace destroy path
recent_net_exit() is called before recent_mt_destroy() in the
destroy path of network namespaces. Make sure there are no entries
in the parent proc entry xt_recent before removing it.
Signed-off-by: Vitaly E. Lavrov <lve@guap.ru>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/xt_hashlimit.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index cc430f926a85..a9d7af953ceb 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -329,7 +329,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo) | |||
329 | parent = hashlimit_net->ipt_hashlimit; | 329 | parent = hashlimit_net->ipt_hashlimit; |
330 | else | 330 | else |
331 | parent = hashlimit_net->ip6t_hashlimit; | 331 | parent = hashlimit_net->ip6t_hashlimit; |
332 | remove_proc_entry(hinfo->pde->name, parent); | 332 | |
333 | if(parent != NULL) | ||
334 | remove_proc_entry(hinfo->pde->name, parent); | ||
335 | |||
333 | htable_selective_cleanup(hinfo, select_all); | 336 | htable_selective_cleanup(hinfo, select_all); |
334 | vfree(hinfo); | 337 | vfree(hinfo); |
335 | } | 338 | } |
@@ -873,6 +876,27 @@ static int __net_init hashlimit_proc_net_init(struct net *net) | |||
873 | 876 | ||
874 | static void __net_exit hashlimit_proc_net_exit(struct net *net) | 877 | static void __net_exit hashlimit_proc_net_exit(struct net *net) |
875 | { | 878 | { |
879 | struct xt_hashlimit_htable *hinfo; | ||
880 | struct hlist_node *pos; | ||
881 | struct proc_dir_entry *pde; | ||
882 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); | ||
883 | |||
884 | /* recent_net_exit() is called before recent_mt_destroy(). Make sure | ||
885 | * that the parent xt_recent proc entry is is empty before trying to | ||
886 | * remove it. | ||
887 | */ | ||
888 | mutex_lock(&hashlimit_mutex); | ||
889 | pde = hashlimit_net->ipt_hashlimit; | ||
890 | if (pde == NULL) | ||
891 | pde = hashlimit_net->ip6t_hashlimit; | ||
892 | |||
893 | hlist_for_each_entry(hinfo, pos, &hashlimit_net->htables, node) | ||
894 | remove_proc_entry(hinfo->pde->name, pde); | ||
895 | |||
896 | hashlimit_net->ipt_hashlimit = NULL; | ||
897 | hashlimit_net->ip6t_hashlimit = NULL; | ||
898 | mutex_unlock(&hashlimit_mutex); | ||
899 | |||
876 | proc_net_remove(net, "ipt_hashlimit"); | 900 | proc_net_remove(net, "ipt_hashlimit"); |
877 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | 901 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
878 | proc_net_remove(net, "ip6t_hashlimit"); | 902 | proc_net_remove(net, "ip6t_hashlimit"); |
@@ -889,9 +913,6 @@ static int __net_init hashlimit_net_init(struct net *net) | |||
889 | 913 | ||
890 | static void __net_exit hashlimit_net_exit(struct net *net) | 914 | static void __net_exit hashlimit_net_exit(struct net *net) |
891 | { | 915 | { |
892 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); | ||
893 | |||
894 | BUG_ON(!hlist_empty(&hashlimit_net->htables)); | ||
895 | hashlimit_proc_net_exit(net); | 916 | hashlimit_proc_net_exit(net); |
896 | } | 917 | } |
897 | 918 | ||