Re: [PATCH net-next] macvlan: fix use-after-free of macvlan_port in macvlan_fill_info()
From: Eric Dumazet
Date: Tue Jun 02 2026 - 05:22:35 EST
On Mon, Jun 1, 2026 at 5:59 PM Kuniyuki Iwashima <kuniyu@xxxxxxxxxx> wrote:
>
> From: Jiayuan Chen <jiayuan.chen@xxxxxxxxx>
> Date: Mon, 1 Jun 2026 14:13:03 +0800
> > This issue was reported by our internal syzkaller [1].
> >
> > rtnl_link_ops->macvlan_fill_info() reads and dereferences
> > 'port = vlan->port'.
> >
> > However, when we delete the underlying physical device of a
> > macvlan (e.g., eth0), we traverse all child macvlan devices and call
> > ndo_uninit -> macvlan_uninit.
> >
> > Each child goes through ndo_uninit -> macvlan_uninit, which
> > synchronously kfree()s the shared port once the last child is gone, but
> > does not clear vlan->port. The child netdevice itself is NOT freed here:
> > its free_netdev() is deferred to netdev_run_todo(), and a concurrent
> > rtnl_getlink() additionally holds a reference via netdev_hold(). So the
> > netdevice stays alive with a now-dangling vlan->port, which
> > macvlan_fill_info() later dereferences -> use-after-free.
> >
> > Here, we set vlan->port = NULL after kfree(port), and then add a NULL check
> > in macvlan_fill_info(). Both kfree(port) and vlan->port = NULL are atomic
> > under the protection of the rtnl lock, so this is safe.
> >
> > In macvlan_fill_info(), if port does not exist, we should simply ignore it
> > and not goto nla_put_failure; otherwise, it would trigger WARN_ON_ONCE(1)
> > in rtnl_getlink().
>
> The splat implies the same class of issues in other devices, so
> I don't think this macvlan-specific fix is the right approach.
>
> We should give up dumping if dev->reg_state is not NETREG_REGISTERED
> after acquiring RTNL, and I think Eric was preparing such a patch ?
>
> https://lore.kernel.org/netdev/CANn89i+UMyx-rKO0ScZkcJYG_vk=_kddcQC+SxbbYSEyUTPgGw@xxxxxxxxxxxxxx/
>
Indeed!
https://lore.kernel.org/netdev/20260602091319.1753654-1-edumazet@xxxxxxxxxx/T/#u
Thanks!