Currently, two bearers of different media types can be added to the
same device (e.g., "eth:eth0" and "ib:eth0"). This causes a leak
in device->dev_refcnt as follows:
tipc_enable_l2_media()
dev_get_by_name()
dev_hold()
As a result, device->dev_refcnt is incremented twice, but the second
bearer replaces the first one.
Fix this by rejecting a bearer with a different media type when the
device is already occupied.
Fixes: cb30a63384bc ("tipc: refactor function tipc_enable_bearer()")
Reported-by: Jiakai Xu <redacted>
Closes: http://lore.kernel.org/netdev/20260918013509.1853952-1-xujiakai24@mails.ucas.ac.cn/ (local)
Signed-off-by: Tung Nguyen <tung.quang.nguyen@est.tech>
---
net/tipc/bearer.c | 10 ++++++++++
1 file changed, 10 insertions(+)
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",--
2.43.0