[hardy CVE 1/1] tunnels: fix netns vs proto registration ordering
Andy Whitcroft
apw at canonical.com
Thu Oct 27 14:08:49 UTC 2011
From: Alexey Dobriyan <adobriyan at gmail.com>
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 at gmail.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
(backported from commit d5aa407f59f5b83d2c50ec88f5bf56d40f1f8978)
CVE-2011-1768
BugLink: http://bugs.launchpad.net/bugs/869215
Signed-off-by: Andy Whitcroft <apw at canonical.com>
---
net/ipv4/ipip.c | 18 ++++++++++--------
net/ipv6/ip6_tunnel.c | 33 +++++++++++++++++----------------
net/ipv6/sit.c | 19 ++++++++++---------
net/ipv6/xfrm6_tunnel.c | 18 +++++++++---------
4 files changed, 46 insertions(+), 42 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 8c2b2b0..44446fd 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -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;
}
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 81941a1..c4e3dd0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -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;
}
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index bd22f64..3e2ce4a 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -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;
}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fae90ff..556491b 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -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
More information about the kernel-team
mailing list