Skip to content

Commit

Permalink
net: mctp: Ensure keys maintain only one ref to corresponding dev
Browse files Browse the repository at this point in the history
[ Upstream commit e4f349b ]

mctp_flow_prepare_output() is called in mctp_route_output(), which
places outbound packets onto a given interface. The packet may represent
a message fragment, in which case we provoke an unbalanced reference
count to the underlying device. This causes trouble if we ever attempt
to remove the interface:

    [   48.702195] usb 1-1: USB disconnect, device number 2
    [   58.883056] unregister_netdevice: waiting for mctpusb0 to become free. Usage count = 2
    [   69.022548] unregister_netdevice: waiting for mctpusb0 to become free. Usage count = 2
    [   79.172568] unregister_netdevice: waiting for mctpusb0 to become free. Usage count = 2
    ...

Predicate the invocation of mctp_dev_set_key() in
mctp_flow_prepare_output() on not already having associated the device
with the key. It's not yet realistic to uphold the property that the key
maintains only one device reference earlier in the transmission sequence
as the route (and therefore the device) may not be known at the time the
key is associated with the socket.

Fixes: 67737c4 ("mctp: Pass flow data & flow release events to drivers")
Acked-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Link: https://patch.msgid.link/20250508-mctp-dev-refcount-v1-1-d4f965c67bb5@codeconstruct.com.au
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Andrew Jeffery authored and Greg Kroah-Hartman committed May 22, 2025
1 parent d38939e commit 1cb9a89
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion net/mctp/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,10 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev)

key = flow->key;

if (WARN_ON(key->dev && key->dev != dev))
if (key->dev) {
WARN_ON(key->dev != dev);
return;
}

mctp_dev_set_key(dev, key);
}
Expand Down

0 comments on commit 1cb9a89

Please sign in to comment.