From c3c0fe0e2bf0b3cbdae4751fb6c708f36fca0c18 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Tue, 16 Feb 2010 09:05:04 +0000
Subject: [PATCH] tunnels: fix netns vs proto registration ordering
Same stuff as in ip_gre patch: receive hook can be called before netns
setup is done, oopsing in net_generic().
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[Also includes fixed for openvz patch kit following this change.]
(backported from commit d5aa407f59f5b83d2c50ec88f5bf56d40f1f8978)
CVE-2011-1768
BugLink: http://bugs.launchpad.net/bugs/869215
Signed-off-by: Andy Whitcroft <apw@canonical.com>
---
.../openvz/patchset/0001-2.6.24-ovz002.patch | 32 ++++++------------
net/ipv4/ipip.c | 18 ++++++-----
net/ipv6/ip6_tunnel.c | 33 ++++++++++---------
net/ipv6/sit.c | 19 ++++++-----
net/ipv6/xfrm6_tunnel.c | 18 +++++-----
5 files changed, 57 insertions(+), 63 deletions(-)
@@ -87076,46 +87076,36 @@ Index: kernel/net/ipv6/sit.c
}
static int __init sit_init(void)
-@@ -832,23 +944,35 @@
- return -EAGAIN;
- }
+@@ -827,11 +939,17 @@ static int __init sit_init(void)
+
+ printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
+#ifdef CONFIG_VE
+ err = sit_ve_start(get_exec_env());
+ if (err)
-+ goto err1;
++ goto out;
+#endif
+
ipip6_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0",
ipip6_tunnel_setup);
if (!ipip6_fb_tunnel_dev) {
err = -ENOMEM;
-- goto err1;
-+ goto err2;
+- goto out;
++ goto err0;
}
ipip6_fb_tunnel_dev->init = ipip6_fb_tunnel_init;
-
- if ((err = register_netdev(ipip6_fb_tunnel_dev)))
-- goto err2;
-+ goto err3;
-+
-+ ve_hook_register(VE_SS_CHAIN, &sit_ve_hook);
-
- out:
- return err;
-- err2:
-+ err3:
+@@ -851,6 +969,10 @@ static int __init sit_init(void)
+ unregister_netdev(ipip6_fb_tunnel_dev);
+ err1:
free_netdev(ipip6_fb_tunnel_dev);
-- err1:
-+ err2:
++ err0:
+#ifdef CONFIG_VE
+ sit_ve_stop(get_exec_env());
-+err1:
+#endif
- xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
goto out;
}
+
Index: kernel/net/ipv6/tcp_ipv6.c
===================================================================
--- kernel.orig/net/ipv6/tcp_ipv6.c 2008-11-18 01:19:47.000000000 +0100
@@ -863,29 +863,31 @@ static int __init ipip_init(void)
printk(banner);
- if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {
- printk(KERN_INFO "ipip init: can't register tunnel\n");
- return -EAGAIN;
- }
-
ipip_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
"tunl0",
ipip_tunnel_setup);
if (!ipip_fb_tunnel_dev) {
err = -ENOMEM;
- goto err1;
+ goto out;
}
ipip_fb_tunnel_dev->init = ipip_fb_tunnel_init;
if ((err = register_netdev(ipip_fb_tunnel_dev)))
+ goto err1;
+
+ if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {
+ printk(KERN_INFO "ipip init: can't register tunnel\n");
+ err = -EAGAIN;
goto err2;
+ }
+
out:
return err;
err2:
- free_netdev(ipip_fb_tunnel_dev);
+ unregister_netdev(ipip_fb_tunnel_dev);
err1:
- xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
+ free_netdev(ipip_fb_tunnel_dev);
goto out;
}
@@ -1396,10 +1396,22 @@ static int __init ip6_tunnel_init(void)
{
int err;
+ ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
+ ip6_tnl_dev_setup);
+ if (!ip6_fb_tnl_dev) {
+ err = -ENOMEM;
+ goto out;
+ }
+ ip6_fb_tnl_dev->init = ip6_fb_tnl_dev_init;
+
+ if ((err = register_netdev(ip6_fb_tnl_dev))) {
+ goto free_netdev;
+ }
+
if (xfrm6_tunnel_register(&ip4ip6_handler, AF_INET)) {
printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n");
err = -EAGAIN;
- goto out;
+ goto unreg_netdev;
}
if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
@@ -1407,24 +1419,13 @@ static int __init ip6_tunnel_init(void)
err = -EAGAIN;
goto unreg_ip4ip6;
}
- ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
- ip6_tnl_dev_setup);
-
- if (!ip6_fb_tnl_dev) {
- err = -ENOMEM;
- goto fail;
- }
- ip6_fb_tnl_dev->init = ip6_fb_tnl_dev_init;
-
- if ((err = register_netdev(ip6_fb_tnl_dev))) {
- free_netdev(ip6_fb_tnl_dev);
- goto fail;
- }
return 0;
-fail:
- xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
unreg_ip4ip6:
xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
+unreg_netdev:
+ unregister_netdev(ip6_fb_tnl_dev);
+free_netdev:
+ free_netdev(ip6_fb_tnl_dev);
out:
return err;
}
@@ -827,29 +827,30 @@ static int __init sit_init(void)
printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
- if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
- printk(KERN_INFO "sit init: Can't add protocol\n");
- return -EAGAIN;
- }
-
ipip6_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0",
ipip6_tunnel_setup);
if (!ipip6_fb_tunnel_dev) {
err = -ENOMEM;
- goto err1;
+ goto out;
}
ipip6_fb_tunnel_dev->init = ipip6_fb_tunnel_init;
- if ((err = register_netdev(ipip6_fb_tunnel_dev)))
+ if ((err = register_netdev(ipip6_fb_tunnel_dev)))
+ goto err1;
+
+ if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
+ printk(KERN_INFO "sit init: Can't add protocol\n");
+ err = -EAGAIN;
goto err2;
+ }
out:
return err;
err2:
- free_netdev(ipip6_fb_tunnel_dev);
+ unregister_netdev(ipip6_fb_tunnel_dev);
err1:
- xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
+ free_netdev(ipip6_fb_tunnel_dev);
goto out;
}
@@ -343,22 +343,22 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = {
static int __init xfrm6_tunnel_init(void)
{
- if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
+ if (xfrm6_tunnel_spi_init() < 0)
return -EAGAIN;
-
- if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
- xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
+
+ if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) {
+ xfrm6_tunnel_spi_fini();
return -EAGAIN;
}
- if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
- xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
+ if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
+ xfrm6_tunnel_spi_fini();
return -EAGAIN;
}
- if (xfrm6_tunnel_spi_init() < 0) {
- xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+ if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
+ xfrm6_tunnel_spi_fini();
return -EAGAIN;
}
return 0;
@@ -366,10 +366,10 @@ static int __init xfrm6_tunnel_init(void)
static void __exit xfrm6_tunnel_fini(void)
{
- xfrm6_tunnel_spi_fini();
xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
+ xfrm6_tunnel_spi_fini();
}
module_init(xfrm6_tunnel_init);
--
1.7.5.4