From: Denis V. Lunev <[email protected]>

ip6_tnl_init_net() frees the ip6_tnl_net of a netns whose VE lacks
VE_FEATURE_IPIP. Only the fallback ip6tnl0 is netns_immutable, so the
host can move any other ip6tnl tunnel into such a container with
"ip link set t6 netns <CT>". ip6_tnl_dellink() looks ip6n up in
dev_net(dev) and reads ip6n->fb_tnl_dev, so the node panics on a NULL
pointer dereference when container root deletes the tunnel, when the
container stops and cleanup_net() deletes it, or when ip6_tunnel is
unloaded.

Take ip6n from t->net, the netns the tunnel was created in and is
hashed in, as changelink, uninit and the ioctl path already do. The
fallback device cannot leave its netns, so the fb_tnl_dev comparison
keeps its meaning.

Fixes: 94e61c310587 ("net/ip6ip: Consider VE_FEATURE_IPIP on new net creation")

https://virtuozzo.atlassian.net/browse/VSTOR-154346
Feature: ve: per-CT features management
Signed-off-by: Denis V. Lunev <[email protected]>
---
 net/ipv6/ip6_tunnel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9694480cdaff..a7667de2c451 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -2095,8 +2095,8 @@ static int ip6_tnl_changelink(struct net_device *dev, 
struct nlattr *tb[],
 
 static void ip6_tnl_dellink(struct net_device *dev, struct list_head *head)
 {
-       struct net *net = dev_net(dev);
-       struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+       struct ip6_tnl *t = netdev_priv(dev);
+       struct ip6_tnl_net *ip6n = net_generic(t->net, ip6_tnl_net_id);
 
        if (dev != ip6n->fb_tnl_dev)
                unregister_netdevice_queue(dev, head);
-- 
2.53.0

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to