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

From: Jiayuan Chen <[email-masked]>
Date: Tue, 17 Mar 2026 17:48:55 +0800

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.

Thanks