[Devel] [PATCH DRAFT vz10 4/5] ve/net/ip6_gre: Fix NULL deref when creating ip6gre/ip6erspan without VE_FEATURE_IPGRE
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Aug 12 16:04:00 MSK 2026
When a Container is not granted VE_FEATURE_IPGRE, ip6gre_init_net()
frees the ip6gre_net_id net_generic slot, so net_generic() returns NULL
for that netns. The guard added by commit 1e1433063539 ("net/gre:
Consider VE_FEATURE_IPGRE on new net creation") was placed in
ip6gre_newlink_common(), but both ip6gre_newlink() and
ip6erspan_newlink() dereference the per-net data (ign) earlier - via
rtnl_dereference(ign->collect_md_tun[_erspan]) and
ip6gre_tunnel_find() -> __ip6gre_bucket() - before ever reaching
ip6gre_newlink_common(). Both rtnl link ops are registered
unconditionally, so a Container without the feature can trigger this by
requesting an "ip6gre" or "ip6erspan" link, dereferencing a NULL ign
and crashing the host.
Move the guard to the top of ip6gre_newlink() and ip6erspan_newlink(),
right after ign is fetched and before it is dereferenced, and drop the
now-redundant check in ip6gre_newlink_common() (its only two callers now
guarantee a non-NULL ign). The changelink paths are not affected: they
operate on an already existing tunnel device, which can only exist when
the feature is on and ign is non-NULL.
Fixes: 1e1433063539 ("net/gre: Consider VE_FEATURE_IPGRE on new net creation")
https://virtuozzo.atlassian.net/browse/VSTOR-141173
Feature: ve: per-CT features management
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
net/ipv6/ip6_gre.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index ba32cc39fc882..fe867528a0c5b 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -2006,15 +2006,6 @@ static int ip6gre_newlink_common(struct net *src_net, struct net_device *dev,
struct ip6_tnl *nt;
struct ip_tunnel_encap ipencap;
int err;
-#ifdef CONFIG_VE
- struct net *net = dev_net(dev);
- struct ip6gre_net *ign;
-
- ign = net_generic(net, ip6gre_net_id);
-
- if (!ign) /* no VE_FEATURE_IPGRE */
- return -EACCES;
-#endif
nt = netdev_priv(dev);
@@ -2054,6 +2045,11 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
ip6gre_netlink_parms(data, &nt->parms);
ign = net_generic(net, ip6gre_net_id);
+#ifdef CONFIG_VE
+ if (!ign) /* no VE_FEATURE_IPGRE */
+ return -EACCES;
+#endif
+
if (nt->parms.collect_md) {
if (rtnl_dereference(ign->collect_md_tun))
return -EEXIST;
@@ -2291,6 +2287,11 @@ static int ip6erspan_newlink(struct net *src_net, struct net_device *dev,
ip6erspan_set_version(data, &nt->parms);
ign = net_generic(net, ip6gre_net_id);
+#ifdef CONFIG_VE
+ if (!ign) /* no VE_FEATURE_IPGRE */
+ return -EACCES;
+#endif
+
if (nt->parms.collect_md) {
if (rtnl_dereference(ign->collect_md_tun_erspan))
return -EEXIST;
--
2.43.0
More information about the Devel
mailing list