The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH net v2] ipvlan: keep lower device alive until private destruction
@ 2026-08-03 12:11 Krystian Kaniewski
  2026-08-03 16:57 ` [syzbot ci] " syzbot ci
  2026-08-06 15:38 ` [PATCH net v2] " Jakub Kicinski
  0 siblings, 2 replies; 3+ messages in thread
From: Krystian Kaniewski @ 2026-08-03 12:11 UTC (permalink / raw)
  To: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: syzkaller-bugs, dskr99, Kees Cook, linux-kernel, syzbot,
	syzbot+5fe14f2ff4ccbace9a26

Commit 40b9d1ab63f5 ("ipvlan: hold lower dev to avoid possible
use-after-free") added a reference to the lower net_device owned by struct
ipvl_port. However, this reference is released when the last
ipvlan_uninit() reduces port->count to zero and calls
ipvlan_port_destroy(), which can happen before all outstanding external
references to the ipvlan netdev have drained.

Specifically, RXE acts as an asynchronous owner in this scenario. RXE
queues RDMA device removal on NETDEV_UNREGISTER, meaning it can retain a
reference to the ipvlan netdev after ndo_uninit has completed. This allows
a later SMC port query to reach the ipvlan device and access its phy_dev.

This leads to the following sequence:
1. The shared ipvl_port owns the reference to the lower net_device
(phy_dev).
2. The last ipvlan_uninit() drops this reference by calling
ipvlan_port_destroy() when port->count reaches zero.
3. RXE retains a reference to the ipvlan netdev, keeping it alive.
4. The lower net_device's refcount drops to 1 and it is freed by
netdev_run_todo(), leaving ipvlan->phy_dev as a dangling pointer. A
subsequent SMC port query accesses this dangling pointer, triggering a
use-after-free.
5. A new per-device hold keeps phy_dev alive until ipvlan_dev_free() runs.

The KASAN report illustrates this use-after-free:

BUG: KASAN: slab-use-after-free in netdev_need_ops_lock
include/net/netdev_lock.h:30 [inline]
BUG: KASAN: slab-use-after-free in netdev_lock_ops
include/net/netdev_lock.h:41 [inline]
BUG: KASAN: slab-use-after-free in __ethtool_get_link_ksettings+0x230/0x250
net/ethtool/ioctl.c:463
Read of size 1 at addr ffff8881988dae09 by task kworker/1:3/1289

Call Trace:
 <TASK>
  __ethtool_get_link_ksettings+0x230/0x250 net/ethtool/ioctl.c:463
  __ethtool_get_link_ksettings+0x11f/0x250 net/ethtool/ioctl.c:464
  ib_get_eth_speed+0x180/0x7f0 drivers/infiniband/core/verbs.c:2052
  rxe_query_port+0x93/0x3d0 drivers/infiniband/sw/rxe/rxe_verbs.c:56
  __ib_query_port drivers/infiniband/core/device.c:2129 [inline]
  ib_query_port+0x16e/0x830 drivers/infiniband/core/device.c:2161
  smc_ib_remember_port_attr net/smc/smc_ib.c:364 [inline]
  smc_ib_port_event_work+0x147/0x920 net/smc/smc_ib.c:388
 </TASK>

Fix this by holding a reference to the lower net_device using a
netdevice_tracker in struct ipvl_dev. The reference is acquired in
ipvlan_init() and released in the priv_destructor callback
(ipvlan_dev_free()). Releasing the reference in ipvlan_dev_free()
guarantees that the lower net_device is held until outstanding external
references to the ipvlan netdev have drained and before final private
teardown and object release. This mirrors the behavior of other stacked
devices like macvlan and vlan, and safely covers ipvtap devices as well.

Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+5fe14f2ff4ccbace9a26@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5fe14f2ff4ccbace9a26
Link: https://syzkaller.appspot.com/ai_job?id=3e3edd19-4e52-49d3-bfdb-ebdde1bda5c3
Signed-off-by: Krystian Kaniewski <krystianmkaniewski@gmail.com>
---
v2:
  - Rebased onto net/main; no code changes.
  - Added the net target-tree prefix.
v1: https://lore.kernel.org/all/26b3176e-d9ed-4508-bde7-388deefd970d@mail.kernel.org/

 drivers/net/ipvlan/ipvlan.h      |  1 +
 drivers/net/ipvlan/ipvlan_main.c | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 80f84fc87008..13cdad00297c 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -64,6 +64,7 @@ struct ipvl_dev {
 	struct list_head	pnode;
 	struct ipvl_port	*port;
 	struct net_device	*phy_dev;
+	netdevice_tracker dev_tracker;
 	struct list_head	addrs;
 	struct ipvl_pcpu_stats	__percpu *pcpu_stats;
 	DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE);
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index ed46439a9f4e..b1435296a0f1 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -162,6 +162,9 @@ static int ipvlan_init(struct net_device *dev)
 	}
 	port = ipvlan_port_get_rtnl(phy_dev);
 	port->count += 1;
+
+	netdev_hold(phy_dev, &ipvlan->dev_tracker, GFP_KERNEL);
+
 	return 0;
 }
 
@@ -673,6 +676,13 @@ void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
 }
 EXPORT_SYMBOL_GPL(ipvlan_link_delete);
 
+static void ipvlan_dev_free(struct net_device *dev)
+{
+	struct ipvl_dev *ipvlan = netdev_priv(dev);
+
+	netdev_put(ipvlan->phy_dev, &ipvlan->dev_tracker);
+}
+
 void ipvlan_link_setup(struct net_device *dev)
 {
 	ether_setup(dev);
@@ -682,6 +692,7 @@ void ipvlan_link_setup(struct net_device *dev)
 	dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;
 	dev->netdev_ops = &ipvlan_netdev_ops;
 	dev->needs_free_netdev = true;
+	dev->priv_destructor = ipvlan_dev_free;
 	dev->header_ops = &ipvlan_header_ops;
 	dev->ethtool_ops = &ipvlan_ethtool_ops;
 }

base-commit: af39eb111ce6b5eba9c08513b62c4868eb7e7fd5
-- 
2.53.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [syzbot ci] Re: ipvlan: keep lower device alive until private destruction
  2026-08-03 12:11 [PATCH net v2] ipvlan: keep lower device alive until private destruction Krystian Kaniewski
@ 2026-08-03 16:57 ` syzbot ci
  2026-08-06 15:38 ` [PATCH net v2] " Jakub Kicinski
  1 sibling, 0 replies; 3+ messages in thread
From: syzbot ci @ 2026-08-03 16:57 UTC (permalink / raw)
  To: andrew, davem, dskr99, edumazet, kees, krystianmkaniewski, kuba,
	linux-kernel, netdev, pabeni, syzbot, syzbot, syzkaller-bugs
  Cc: syzbot, syzkaller-bugs

syzbot ci has tested the following series

[v2] ipvlan: keep lower device alive until private destruction
https://lore.kernel.org/all/20260803121140.261329-1-krystianmkaniewski@gmail.com
* [PATCH net v2] ipvlan: keep lower device alive until private destruction

and found no issues.

Full report is available here:
https://ci.syzbot.org/series/33f00e49-faea-4860-a29a-c8b4792c5338

***

If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
  Tested-by: syzbot@syzkaller.appspotmail.com

---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net v2] ipvlan: keep lower device alive until private destruction
  2026-08-03 12:11 [PATCH net v2] ipvlan: keep lower device alive until private destruction Krystian Kaniewski
  2026-08-03 16:57 ` [syzbot ci] " syzbot ci
@ 2026-08-06 15:38 ` Jakub Kicinski
  1 sibling, 0 replies; 3+ messages in thread
From: Jakub Kicinski @ 2026-08-06 15:38 UTC (permalink / raw)
  To: Krystian Kaniewski
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
	syzkaller-bugs, dskr99, Kees Cook, linux-kernel, syzbot,
	syzbot+5fe14f2ff4ccbace9a26

On Mon,  3 Aug 2026 14:11:39 +0200 Krystian Kaniewski wrote:
> Specifically, RXE acts as an asynchronous owner in this scenario. RXE
> queues RDMA device removal on NETDEV_UNREGISTER, meaning it can retain a
> reference to the ipvlan netdev after ndo_uninit has completed.

The netdev reference only guarantees that struct net_device does not 
go away. Caller must check that the device is still alive if it is
trying to operate on it without a guarantee that it's still live.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-06 15:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 12:11 [PATCH net v2] ipvlan: keep lower device alive until private destruction Krystian Kaniewski
2026-08-03 16:57 ` [syzbot ci] " syzbot ci
2026-08-06 15:38 ` [PATCH net v2] " Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox