Netdev List
 help / color / mirror / Atom feed
* [PATCH] vsock/hv_sock: fix socket/table leak when rescind races the delayed close
@ 2026-09-17 22:02 Bartłomiej Dmitruk
  2026-09-18  2:56 ` Ivy Lopez
  2026-09-21 23:23 ` netdev-bot+sashiko
  0 siblings, 2 replies; 4+ messages in thread
From: Bartłomiej Dmitruk @ 2026-09-17 22:02 UTC (permalink / raw)
  To: Dexuan Cui, Wei Liu, Haiyang Zhang, K . Y . Srinivasan
  Cc: linux-hyperv, netdev, Stefano Garzarella, Michael S . Tsirkin

hvs_close_lock_held() takes a scheduling reference (sock_hold()) and
schedules hvs_close_timeout(); that reference is dropped, with
vsock_remove_sock(), by the delayed close.

hvs_do_close_lock_held(vsk, cancel_timeout=true) drops the reference and
removes the socket only if cancel_delayed_work() succeeds.  When the host
rescind callback hvs_close_connection() runs while hvs_close_timeout() is
already dequeued and blocked on lock_sock(), cancel_delayed_work() returns
false: the reference is not dropped and the socket is not removed, only
SOCK_DONE is set.  hvs_close_timeout() then sees SOCK_DONE, skips
hvs_do_close_lock_held(), and drops only its own local reference -- the
scheduling reference leaks and the socket is never removed from the
bound/connected tables.

Make the running timeout complete the cleanup the rescind path could not:
when SOCK_DONE is set but the work is still marked scheduled, drop the
scheduling reference and remove the socket.  The two cleanup sites are
mutually exclusive and guarded by close_work_scheduled, so the reference
is dropped exactly once.  (cancel_delayed_work_sync() cannot be used from
hvs_do_close_lock_held(): it runs under the same lock_sock() the work
takes.)

Signed-off-by: Bartłomiej Dmitruk <bartlomiej.dmitruk@isec.pl>
---
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -499,10 +499,18 @@
 
 	sock_hold(sk);
 	lock_sock(sk);
-	if (!sock_flag(sk, SOCK_DONE))
+	if (!sock_flag(sk, SOCK_DONE)) {
 		hvs_do_close_lock_held(vsk, false);
-
-	vsk->close_work_scheduled = false;
+	} else if (vsk->close_work_scheduled) {
+		/* A concurrent rescind (hvs_close_connection) set SOCK_DONE but
+		 * could not cancel this already-running work, so it left the
+		 * scheduling reference and vsock_remove_sock() to us.  Finish
+		 * the cleanup to avoid leaking the socket and its table entry.
+		 */
+		vsk->close_work_scheduled = false;
+		vsock_remove_sock(vsk);
+		sock_put(sk);
+	}
 	release_sock(sk);
 	sock_put(sk);
 }

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

end of thread, other threads:[~2026-09-21 23:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-17 22:02 [PATCH] vsock/hv_sock: fix socket/table leak when rescind races the delayed close Bartłomiej Dmitruk
2026-09-18  2:56 ` Ivy Lopez
2026-09-18 12:47   ` Stefano Garzarella
2026-09-21 23:23 ` netdev-bot+sashiko

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