DORMANTno replies

[PATCH] tipc: refuse to attach a second bearer to a netdevice

From: Jiakai Xu <hidden>
Date: 2026-09-18 01:35:31
Also in: lkml
Subsystem: networking [general], the rest, tipc network layer · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Jon Maloy, Tung Quang Nguyen

tipc_enable_l2_media() associates a bearer with a netdevice by
unconditionally overwriting dev->tipc_ptr.  The duplicate check in
tipc_enable_bearer() only compares full bearer names, so two bearers
of different media types over the same device (e.g. "eth:team0" and
"ib:team0") can both be enabled successfully.  The second one then
silently replaces dev->tipc_ptr.

Each successful enable holds one device reference obtained with
dev_get_by_name().  Since the device notifier tipc_l2_device_event()
only sees the bearer pointed to by dev->tipc_ptr, NETDEV_UNREGISTER
disables only the last attached bearer; the other bearer is never
disabled and its device reference is leaked for good.  The leaked
bearer keeps sending periodic discovery requests on the unregistered
device, producing endless "selects TX queue" warnings and stalling
the device teardown (unregister_netdevice: waiting for ... to become
free).  This was observed by syzkaller with team slaves.

Fix this by rejecting the enable with -EBUSY when the device already
has a bearer attached.  The caller tipc_enable_bearer() already rolls
the new bearer back on any enable_media() failure.

Fixes: 37cb0620073c ("tipc: remove TIPC usage of field af_packet_priv in struct net_device")
Signed-off-by: Jiakai Xu <redacted>
---
 net/tipc/bearer.c | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 05dcd2f9e887a..b15a67429fe5a 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -454,6 +454,13 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
 		return -EINVAL;
 	}
 
+	/* Only one TIPC bearer may be attached to a device at a time */
+	if (rtnl_dereference(dev->tipc_ptr)) {
+		dev_put(dev);
+		pr_warn("Device %s already used by another bearer\n", dev->name);
+		return -EBUSY;
+	}
+
 	/* Associate TIPC bearer with L2 bearer */
 	rcu_assign_pointer(b->media_ptr, dev);
 	b->pt.dev = dev;
-- 
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help