Thread (3 messages) flat view 3 messages, 2 authors, 4d ago

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

From: Tung Quang Nguyen <tung.quang.nguyen@est.tech>
Date: 2026-09-21 02:06:33
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

-----Original Message-----
From: Jiakai Xu <redacted>
Sent: September 18, 2026 08:35
To: netdev@vger.kernel.org; Jon Maloy <jmaloy@redhat.com>; Tung Quang
Nguyen [off-list ref]
Cc: David S . Miller <davem@davemloft.net>; Eric Dumazet
[off-list ref]; Jakub Kicinski [off-list ref]; Paolo Abeni
[off-list ref]; Simon Horman [off-list ref]; Ying Xue
[off-list ref]; Paul Gortmaker
[off-list ref]; tipc-discussion@lists.sourceforge.net;
linux-kernel@vger.kernel.org; Jiakai Xu [off-list ref]
Subject: [PATCH] tipc: refuse to attach a second bearer to a netdevice

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")
This does not seem to be the patch that introduced the issue.
quoted hunk ↗ jump to hunk
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);
This API is deprecated.
+		pr_warn("Device %s already used by another bearer\n", dev-
quoted
name);
Line exceeds 80 columns.
Accessing dev->name after calling dev_put() is not a safe thing to do.
+		return -EBUSY;
This error code suggests that it is possible to attach the second bearer after some time.
By the way, the sanity check should be performed earlier like below. Can you help test this patch ?
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 05dcd2f9e887..1fb54a588c8d 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -258,6 +258,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
        int bearer_id = 0;
        int res = -EINVAL;
        char *errstr = "";
+       char *if_name;
        u32 i;
 
        if (!bearer_name_validate(name, &b_names)) {
@@ -296,6 +297,15 @@ static int tipc_enable_bearer(struct net *net, const char *name,
                        goto rejected;
                }
 
+               if_name = strchr((const char *)b->name, ':') + 1;
+               if (!strcmp(if_name, b_names.if_name) &&
+                   strcmp(b->media->name, b_names.media_name)) {
+                       errstr = "same device for different media";
+                       NL_SET_ERR_MSG(extack,
+                                      "Same device for different media");
+                       goto rejected;
+               }
+
                if (b->priority == prio &&
                    (++with_this_prio > 2)) {
                        pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help