Subject: Re: [PATCH net v1] IB/core: Fix use-after-free of ipvlan phy_dev in ib_get_eth_speed

From: Leon Romanovsky <[email-masked]>
Date: Tue, 17 Mar 2026 15:41:41 +0200

On Tue, Mar 17, 2026 at 05:48:55PM +0800, Jiayuan Chen wrote:
> 
> On 3/17/26 12:29 AM, Leon Romanovsky wrote:
> > On Wed, Mar 11, 2026 at 06:03:08PM +0800, Jiayuan Chen wrote:
> > > From: Jiayuan Chen <[email-masked]>
> > > 
> > > Jianzhou Zhao reported a NULL pointer dereference in
> > > __ethtool_get_link_ksettings [1]. The root cause is a use-after-free
> > > of ipvlan->phy_dev.
> > > 
> > > In ib_get_eth_speed(), ib_device_get_netdev() obtains a reference to the
> > > ipvlan device outside of rtnl_lock(). This creates a race window: between
> > > ib_device_get_netdev() and rtnl_lock(), the underlying phy_dev (e.g. a
> > > dummy device) can be unregistered and freed by another thread.
> > If ib_device_get_netdev() worked as it was supposed to work, it can't.
> > That function grabs reference on netdev and returns or netdev with elevated
> > reference counter which can't be freed or returns NULL.
> > 
> > Thanks
> > 
> 
> ipvlan's phy_dev is safe in the data path — TX/RX runs in softirq
> context with RCU protection, no lock needed per packet.
> 
> The issue here is in the control path. __ethtool_get_link_ksettings()
> requires rtnl_lock() — all existing ethtool callers follow this:
> 
> - ioctl path: rtnl_lock() is taken first, then __dev_get_by_name()
> looks up the dev without even holding a refcnt — relying entirely
> on RTNL for safety. (net/ethtool/ioctl.c:3571, 3249)
> - netlink path: dev is looked up with refcnt first, but the actual
> ethtool ops run under rtnl_lock(). (net/ethtool/netlink.c:527-533)
> 
> Under RTNL, phy_dev cannot disappear because phy_dev unregistration
> triggers NETDEV_UNREGISTER which deletes ipvlan first — all within
> the same RTNL context. That's why no virtual netdev driver (ipvlan,
> macvlan, bond, etc.) holds an extra refcnt on the lower dev in its
> ethtool callbacks.
> 
> ib_get_eth_speed() calls __ethtool_get_link_ksettings() under
> rtnl_lock(), but obtains the netdev before it. Moving the lookup
> inside rtnl_lock() makes the netdev resolution and ethtool call
> atomic w.r.t. device unregistration, consistent with how ethtool's
> own paths work.

Please reread my earlier response and explain how an ipvlan device can
disappear immediately after a successful call to ib_device_get_netdev().

Thanks

> Thanks