Linux CAN drivers development
 help / color / mirror / Atom feed
* [PATCH net] can: isotp: take rtnl_lock() before leaving the notifier list
@ 2026-08-31  8:30 Norbert Szetei
  2026-08-31 13:08 ` Oliver Hartkopp
  0 siblings, 1 reply; 4+ messages in thread
From: Norbert Szetei @ 2026-08-31  8:30 UTC (permalink / raw)
  To: linux-can; +Cc: Oliver Hartkopp, Marc Kleine-Budde, linux-kernel

isotp_release() removes the socket from isotp_notifier_list before it
takes rtnl_lock(). The netdev notifier chain runs under RTNL, so a
socket that leaves the list in that window is skipped by isotp_notify()
and has to unregister its own CAN filters.

It cannot always do that. isotp_release() passes sock_net(sk) to
can_rx_unregister(), which returns early when that netns no longer
matches dev_net(dev), before the receiver list is searched and before
the "receive list entry not found" warning. Once the bound device has
been moved to another netns the filters are removed zero times, and
can_rx_register() stores rcv->sk without taking a reference, so the
receivers left in the device's dev_rcv_lists point at the freed socket
and travel with the device into the new netns.

  BUG: KASAN: use-after-free in isotp_rcv+0x1570/0x24d0
  Read of size 1 at addr ffff888118130552 by task isotp_ns_uaf/578
   can_rcv_filter+0x4af/0x8c0
   can_receive+0x28d/0x3c0
   can_rcv+0x2a9/0x310
   __netif_receive_skb_one_core+0x21a/0x260
   process_backlog+0x210/0x760

Take rtnl_lock() before removing the socket from the notifier list, so
that isotp_release() and isotp_notify() cannot both skip the removal.

Fixes: 20bab8b88baa ("can: isotp: fix use-after-free race with concurrent NETDEV_UNREGISTER")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
---
Reproducer available on request.

 net/can/isotp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/can/isotp.c b/net/can/isotp.c
index 155530aedce2..8ca75d30360c 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1475,6 +1475,8 @@ static int isotp_release(struct socket *sock)
 	/* forced SHUTDOWN may have skipped IDLE (gave up on a signal) */
 	wake_up_interruptible(&so->wait);
 
+	rtnl_lock();
+
 	spin_lock(&isotp_notifier_lock);
 	while (isotp_busy_notifier == so) {
 		spin_unlock(&isotp_notifier_lock);
@@ -1484,7 +1486,6 @@ static int isotp_release(struct socket *sock)
 	list_del(&so->notifier);
 	spin_unlock(&isotp_notifier_lock);
 
-	rtnl_lock();
 	lock_sock(sk);
 
 	/* remove current filters & unregister
-- 
2.55.0


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

end of thread, other threads:[~2026-09-01 10:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31  8:30 [PATCH net] can: isotp: take rtnl_lock() before leaving the notifier list Norbert Szetei
2026-08-31 13:08 ` Oliver Hartkopp
2026-09-01  7:01   ` Norbert Szetei
2026-09-01 10:25     ` Oliver Hartkopp

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