summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Pidoux <bernard.f6bvp@gmail.com>2026-05-27 14:11:21 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-06-27 11:07:40 +0100
commit25982d734933184ef8c9a5d8c6ce782321e23324 (patch)
tree7d6484003705b632baa308fe2b1f74f44f07b692
parent4e5848f3e04be9f427fa912a15cc54f032f059cd (diff)
downloadlinux-25982d734933184ef8c9a5d8c6ce782321e23324.tar.gz
linux-25982d734933184ef8c9a5d8c6ce782321e23324.zip
rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup
commit 741a4863ad570889c75f7a8e404567d8f3e46335 upstream. When rose_kill_by_device() is called (via NETDEV_DOWN on module exit or interface removal), it calls rose_disconnect() which transitions sockets to ROSE_STATE_0 and sets SOCK_DEAD. However, rose_heartbeat_expiry() only calls rose_destroy_socket() at ROSE_STATE_0 if SOCK_DESTROY is set -- the SOCK_DEAD path is reserved for TCP_LISTEN sockets. Without SOCK_DESTROY, orphaned sockets in ROSE_STATE_2 (clearing) loop indefinitely in the heartbeat without ever being freed, keeping the module use-count elevated and blocking modprobe -r rose until the T1 timer (up to 200 s) expires. Set SOCK_DESTROY immediately after rose_disconnect() so the heartbeat destroys the socket at its next tick (within 5 s), allowing clean module unload. Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/rose/af_rose.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 64dfdf398ee0..35099cd6ee19 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -211,6 +211,11 @@ start:
spin_lock_bh(&rose_list_lock);
if (rose->device == dev) {
rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+ /* Mark for destruction so rose_heartbeat_expiry()
+ * cleans up the socket at its next tick rather than
+ * looping forever in ROSE_STATE_0 with no owner.
+ */
+ sock_set_flag(sk, SOCK_DESTROY);
if (rose->neighbour)
rose_neigh_put(rose->neighbour);
netdev_put(rose->device, &rose->dev_tracker);