Thread (28 messages) 28 messages, 3 authors, 22d ago

Re: [PATCH net-next 2/9] vxlan: vnifilter: free vxlan_vni_group via RCU in vxlan_vnigroup_uninit()

From: Eric Dumazet <edumazet@google.com>
Date: 2026-09-06 15:41:05

On Sat, Sep 5, 2026 at 6:52 AM Kuniyuki Iwashima [off-list ref] wrote:
On Thu, Sep 3, 2026 at 5:08 AM Eric Dumazet [off-list ref] wrote:
quoted
vxlan->vnigrp is an RCU-protected pointer accessed locklessly under
rcu_read_lock() in vxlan_vnifilter_dump_dev().

Currently, vxlan_vnigroup_uninit() frees struct vxlan_vni_group
synchronously via kfree(vg). If a VXLAN device is deleted concurrently
with an RTM_GETTUNNEL dump, vxlan_vnifilter_dump_dev() can suffer a
use-after-free when reading vg->num_vnis or walking vg->vni_list.
In unregister_netdevice_many_notify(), does synchronize_net() after
unlist_netdevice() wait for the reader to complete before ->ndo_uninit() ?
Good point. I added this patch after sashiko had a false positive:

<quote>
 @@ -2979,10 +3007,13 @@ static int vxlan_init(struct net_device *dev)
 static void vxlan_uninit(struct net_device *dev)
 {
  struct vxlan_dev *vxlan = netdev_priv(dev);
+ const struct vxlan_config *cfg;
+
+ cfg = rtnl_dereference(vxlan->cfg);

  vxlan_mdb_fini(vxlan);

- if (vxlan->cfg.flags & VXLAN_F_VNIFILTER)
+ if (cfg && (cfg->flags & VXLAN_F_VNIFILTER))
  vxlan_vnigroup_uninit(vxlan);
This is a pre-existing issue, but does this synchronous cleanup cause a
use-after-free for concurrent RCU readers?
Looking at vxlan_vnigroup_uninit() in drivers/net/vxlan/vxlan_vnifilter.c
around line 925, it destroys and frees the RCU-protected vxlan_vni_group
synchronously:
drivers/net/vxlan/vxlan_vnifilter.c:vxlan_vnigroup_uninit() {
    ...
    rhashtable_destroy(&vg->vni_hash);
    kfree(vg);
}
Concurrently, a netlink dump for RTM_GETTUNNEL could call
vxlan_vnifilter_dump_dev(), which retrieves the device under RCU and
accesses vxlan->vnigrp via rcu_dereference(). If the vxlan device is
deleted at the same time, unregister_netdevice_many() calls ndo_uninit() ->
vxlan_uninit() -> vxlan_vnigroup_uninit(), which frees vg without waiting
for an RCU grace period.
Could this lead to memory corruption, and should it be using kfree_rcu()
or synchronize_rcu() instead?

</quote>

Sashiko saw vxlan->vnigrp annotated as __rcu and read under
rcu_read_lock() in vxlan_vnifilter_dump_dev(),
and assumed that because vxlan_vnigroup_uninit() directly does
kfree(vg) without an RCU grace period,
a concurrent netlink dump could hit a UAF.

However, Sashiko missed the netdevice unregistration sequence in
net/core/dev.c: unlist_netdevice(dev)
unlinks the device from lookup structures and synchronize_net() waits
for all active readers to complete
before dev->netdev_ops->ndo_uninit() is ever called.

I will drop this patch from V2 then.

Thanks.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help