Re: [PATCH net v1] IB/core: Fix use-after-free of ipvlan phy_dev in ib_get_eth_speed
From: Leon Romanovsky <leon@kernel.org>
Date: 2026-03-17 13:41:46
Also in:
linux-rdma, lkml
On Tue, Mar 17, 2026 at 05:48:55PM +0800, Jiayuan Chen wrote:
On 3/17/26 12:29 AM, Leon Romanovsky wrote:quoted
On Wed, Mar 11, 2026 at 06:03:08PM +0800, Jiayuan Chen wrote:quoted
From: Jiayuan Chen <redacted> 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. Thanksipvlan'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