diff options
| author | Bernard Pidoux <bernard.f6bvp@gmail.com> | 2026-05-27 14:11:21 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-06-27 11:07:40 +0100 |
| commit | 25982d734933184ef8c9a5d8c6ce782321e23324 (patch) | |
| tree | 7d6484003705b632baa308fe2b1f74f44f07b692 | |
| parent | 4e5848f3e04be9f427fa912a15cc54f032f059cd (diff) | |
| download | linux-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.c | 5 |
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); |
