tipc_topsrv_stop() destroyed the receive workqueue while the listener socket still had its data-ready callback and sk_user_data installed. An incoming connection request could then queue srv->awork on the freed workqueue from tipc_topsrv_listener_data_ready(). Reject new accepts, clear sk_user_data under sk_callback_lock and cancel pending accept work before the workqueues are torn down. Fixes: 0ef897be12b8 ("tipc: separate topology server listener socket from subcsriber sockets") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: LLM Signed-off-by: Yuqi Xu Reviewed-by: Ren Wei --- net/tipc/topsrv.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index af530c9ed840..908622a3d0fc 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c @@ -700,6 +700,15 @@ static void tipc_topsrv_stop(struct net *net) struct tipc_conn *con; int id; + spin_lock_bh(&srv->idr_lock); + srv->listener = NULL; + spin_unlock_bh(&srv->idr_lock); + + write_lock_bh(&lsock->sk->sk_callback_lock); + lsock->sk->sk_user_data = NULL; + write_unlock_bh(&lsock->sk->sk_callback_lock); + cancel_work_sync(&srv->awork); + spin_lock_bh(&srv->idr_lock); for (id = 0; srv->idr_in_use; id++) { con = idr_find(&srv->conn_idr, id); @@ -713,7 +722,6 @@ static void tipc_topsrv_stop(struct net *net) } __module_get(lsock->ops->owner); __module_get(lsock->sk->sk_prot_creator->owner); - srv->listener = NULL; spin_unlock_bh(&srv->idr_lock); tipc_topsrv_work_stop(srv); -- 2.55.0