Merge branch 'vxlan-geneve-require-cap_net_admin-in-the-device-netns-for-changelink'

Doruk Tan Ozturk says:

====================
vxlan, geneve: require CAP_NET_ADMIN in the device netns for changelink

The recent series "require CAP_NET_ADMIN in the device netns for
changelink" (8165f7ff57d9..27ccb68e7ccc) added rtnl_dev_link_net_capable()
and gated the eight IP tunnel drivers (ip_gre, ipip, ip_vti, ip6_tunnel,
ip6_gre, ip6_vti, sit, xfrm_interface). VXLAN and GENEVE share the exact
same shape but were not covered: both store the underlay netns sticky at
newlink (vxlan->net / geneve->net) and their changelink() operates on that
netns, while the generic RTM_NEWLINK path only checks CAP_NET_ADMIN against
dev_net(dev). Once such a device is created in or moved to another netns,
a caller privileged in dev_net(dev) but not in the underlay netns can
reconfigure the tunnel'"'"'s underlay.

This completes that series for the two UDP tunnel drivers that were left
out. Same helper, same placement (top of changelink, before any attribute
is parsed).

Verified on next-20260714 in QEMU with CONFIG_VXLAN=y + CONFIG_USER_NS=y:
an unprivileged user namespace holding CAP_NET_ADMIN only in a child netns
issues an IFLA_INFO_DATA changelink on a vxlan device whose underlay lives
in init_net. Before: returns 0 (reconfigures the init_net underlay).
After: returns -EPERM.
====================

Link: https://patch.msgid.link/20260716203500.70573-1-doruk@0sec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-07-23 08:17:10 -07:00
commit 9857fc06eb
2 changed files with 6 additions and 0 deletions

View File

@ -2394,6 +2394,9 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
struct geneve_config cfg;
int err;
if (!rtnl_dev_link_net_capable(dev, geneve->net))
return -EPERM;
/* If the geneve device is configured for metadata (or externally
* controlled, for example, OVS), then nothing can be changed.
*/

View File

@ -4421,6 +4421,9 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
struct vxlan_rdst *dst;
int err;
if (!rtnl_dev_link_net_capable(dev, vxlan->net))
return -EPERM;
dst = &vxlan->default_dst;
err = vxlan_nl2conf(tb, data, dev, &conf, true, extack);
if (err)