From: Hyunwoo Kim <imv4bel@gmail.com>
To: sgarzare@redhat.com, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
mhal@rbox.co, leonardi@redhat.com, bobbyeshleman@meta.com,
stefanha@redhat.com, mst@redhat.com
Cc: virtualization@lists.linux.dev, netdev@vger.kernel.org,
imv4bel@gmail.com
Subject: [PATCH net] vsock: do not reset a socket in connect() once it has connected
Date: Thu, 13 Aug 2026 05:13:09 +0900 [thread overview]
Message-ID: <anzT1fREOSyHT99k@v4bel> (raw)
commit 002541ef650b ("vsock: Ignore signal/timeout on connect() if
already established") stopped connect() from resetting an established
socket. The check only looks at whether sk_state is TCP_ESTABLISHED at
that moment, and the state can change while connect() sleeps.
A peer RST moves the socket to TCP_CLOSING, and it is not removed from
vsock_connected_table on that path. connect() then wakes up, fails the
check, and resets a socket that had actually connected to TCP_CLOSE and
SS_UNCONNECTED.
The socket can now be connected again while it is still on the table.
Reconnecting to an address served by a different transport makes
vsock_assign_transport() drop the transport from a live socket and free
vsk->trans, even if skbs it already sent are still in flight.
Reconnecting to the same address inserts a node that is already on the
table, provided shutdown() has cleared SOCK_DONE in between.
sock->state cannot be used for the check either. shutdown() overwrites
SS_CONNECTED with SS_DISCONNECTING.
Record on the socket that the connection completed, and check that
instead. The sk_err path after the loop does the same reset, so guard it
as well.
Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
---
include/net/af_vsock.h | 2 ++
net/vmw_vsock/af_vsock.c | 12 ++++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 30046a3c20f735..d7ec976ed6e272 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -63,6 +63,8 @@ struct vsock_sock {
struct delayed_work pending_work;
struct delayed_work close_work;
bool close_work_scheduled;
+ /* Set once the connection completed; never cleared. */
+ bool ever_connected;
u32 peer_shutdown;
bool sent_request;
bool ignore_connecting_rst;
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 622dbd04679944..735c91bb762242 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -351,6 +351,8 @@ void vsock_insert_connected(struct vsock_sock *vsk)
struct list_head *list = vsock_connected_sockets(
&vsk->remote_addr, &vsk->local_addr);
+ vsk->ever_connected = true;
+
spin_lock_bh(&vsock_table_lock);
__vsock_insert_connected(list, vsk);
spin_unlock_bh(&vsock_table_lock);
@@ -1814,14 +1816,14 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
* Note that allowing to "reset" an already established socket
* here is racy and insecure.
*/
- if (sk->sk_state == TCP_ESTABLISHED)
+ if (vsk->ever_connected)
break;
/* If connection was _not_ established and a signal/timeout came
* to be, we want the socket's state reset. User space may want
* to retry.
*
- * sk_state != TCP_ESTABLISHED implies that socket is not on
+ * !ever_connected implies that socket is not on
* vsock_connected_table. We keep the binding and the transport
* assigned.
*/
@@ -1849,8 +1851,10 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
if (sk->sk_err) {
err = -sk->sk_err;
- sk->sk_state = TCP_CLOSE;
- sock->state = SS_UNCONNECTED;
+ if (!vsk->ever_connected) {
+ sk->sk_state = TCP_CLOSE;
+ sock->state = SS_UNCONNECTED;
+ }
} else {
err = 0;
}
--
2.43.0
next reply other threads:[~2026-08-12 20:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 20:13 Hyunwoo Kim [this message]
2026-08-13 9:42 ` [PATCH net] vsock: do not reset a socket in connect() once it has connected Michal Luczaj
2026-08-14 1:45 ` Hyunwoo Kim
2026-08-16 22:29 ` Michal Luczaj
2026-08-19 8:54 ` Stefano Garzarella
2026-09-07 18:35 ` Hyunwoo Kim
2026-09-08 15:17 ` Michal Luczaj
2026-09-09 22:06 ` Michal Luczaj
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=anzT1fREOSyHT99k@v4bel \
--to=imv4bel@gmail.com \
--cc=bobbyeshleman@meta.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=leonardi@redhat.com \
--cc=mhal@rbox.co \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sgarzare@redhat.com \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.