Thread (20 messages) 20 messages, 3 authors, 2d ago
WARM2d

[PATCH net v3 6/8] vsock: handle socket bricking due to transport event

From: Michal Luczaj <hidden>
Date: 2026-09-22 13:15:36
Also in: kvm, lkml, virtualization
Subsystem: networking [general], the rest, vm sockets (af_vsock) · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Stefano Garzarella

Transport events are serviced by resetting each connected socket. The reset
is done under vsock_table_lock but without taking lock_sock(), so from the
point of view of vsock_connect() - locklessly. The same pattern is present
in virtio_vsock_reset_sock(), vmci_transport_handle_detach() and
vhost_vsock_reset_orphans().

While connect() waits for TCP_SYN_SENT -> TCP_ESTABLISHED, other
transitions can also occur:

  TCP_SYN_SENT -> TCP_CLOSE on connection failure, timeout or signal
  TCP_SYN_SENT -> TCP_ESTABLISHED -> TCP_CLOSING on VIRTIO_VSOCK_OP_RST
  TCP_SYN_SENT -> TCP_ESTABLISHED -> [TCP_CLOSING ->] TCP_CLOSE on event

But transport events leave SS_CONNECTED state unchanged. So take a note of
that, rather than a) making every event handler drop the socket from
connected_table, or b) adapting connect() to handle more transitions (while
missing proper locking).

Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
Signed-off-by: Michal Luczaj <redacted>
---
 net/vmw_vsock/af_vsock.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index ff4140aaf1f3..5a2d7e10ecb8 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1663,6 +1663,19 @@ static void vsock_unconnected_reset(struct sock *sk)
 
 	sock_owned_by_me(sk);
 
+	/*
+	 * Transport events are serviced by resetting each connected socket to
+	 * TCP_CLOSE. The reset is done under vsock_table_lock but without
+	 * taking lock_sock(), so it is effectively lockless from the
+	 * perspective of connect().
+	 *
+	 * Preserve socket's bricked status. Also check SS_DISCONNECTING, since
+	 * shutdown() may race us.
+	 */
+	if (sk->sk_socket->state == SS_CONNECTED ||
+	    sk->sk_socket->state == SS_DISCONNECTING)
+		return;
+
 	/*
 	 * Only connected socks may have peer_shutdown or SOCK_DONE set.
 	 *
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help