summaryrefslogtreecommitdiffstats
path: root/net/netfilter/ipvs
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2012-07-07 20:30:11 +0300
committerPablo Neira Ayuso <pablo@netfilter.org>2012-07-17 12:00:58 +0200
commit283283c4da91adc44b03519f434ee1e7e91d6fdb (patch)
treee37e991a30b63ff5fd7e2363bd361a93db545e5b /net/netfilter/ipvs
parent9e33ce453f8ac8452649802bee1f410319408f4b (diff)
downloadlinux-283283c4da91adc44b03519f434ee1e7e91d6fdb.tar.gz
linux-283283c4da91adc44b03519f434ee1e7e91d6fdb.tar.bz2
linux-283283c4da91adc44b03519f434ee1e7e91d6fdb.zip
ipvs: fix oops in ip_vs_dst_event on rmmod
After commit 39f618b4fd95ae243d940ec64c961009c74e3333 (3.4) "ipvs: reset ipvs pointer in netns" we can oops in ip_vs_dst_event on rmmod ip_vs because ip_vs_control_cleanup is called after the ipvs_core_ops subsys is unregistered and net->ipvs is NULL. Fix it by exiting early from ip_vs_dst_event if ipvs is NULL. It is safe because all services and dests for the net are already freed. Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/ipvs')
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index d43e3c122f7b..84444dda194b 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1521,11 +1521,12 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = ptr;
struct net *net = dev_net(dev);
+ struct netns_ipvs *ipvs = net_ipvs(net);
struct ip_vs_service *svc;
struct ip_vs_dest *dest;
unsigned int idx;
- if (event != NETDEV_UNREGISTER)
+ if (event != NETDEV_UNREGISTER || !ipvs)
return NOTIFY_DONE;
IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name);
EnterFunction(2);
@@ -1551,7 +1552,7 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event,
}
}
- list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) {
+ list_for_each_entry(dest, &ipvs->dest_trash, n_list) {
__ip_vs_dev_reset(dest, dev);
}
mutex_unlock(&__ip_vs_mutex);