From: netdev-bot+sashiko@kernel.org
To: mhal@rbox.co
Cc: stefanha@redhat.com, sgarzare@redhat.com, mst@redhat.com,
jasowangio@gmail.com, eperezma@redhat.com, davem@davemloft.net,
xuanzhuo@linux.alibaba.com, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, kvm@vger.kernel.org,
virtualization@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, imv4bel@gmail.com
Subject: Re: [PATCH net v3 5/8] vsock: treat TCP_CLOSING as once-established
Date: Thu, 24 Sep 2026 13:15:05 +0000 [thread overview]
Message-ID: <179025570581.2160803.6664724141686428896@kernel.org> (raw)
In-Reply-To: <20260922-vsock-connect-reset-closing-v3-5-78907b8200d4@rbox.co>
Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider.
Critical: 0 · High: 1 · Medium: 0 · Low: 1
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [High] The failed-connect cleanup at the out_reset label of
vsock_connect() (net/vmw_vsock/af_vsock.c:1883-1884), which this patch…
- [Low] Concern (validated as NOT a defect to report against this
series): the new short-circuit in vsock_connect() enumerates only…
--
vsock: treat TCP_CLOSING as once-established
The patch makes blocking connect() stop treating a socket that already
reached TCP_ESTABLISHED and then moved to TCP_CLOSING (or picked up an
sk_err) as a failed connection attempt, returning 0 instead. It also makes
the out_reset cleanup call vsock_unconnected_reset() unconditionally rather
than only when err is non-zero.
Link: https://lore.kernel.org/netdev/anzT1fREOSyHT99k@v4bel/
> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> index 5cecd1c9c6e50..ff4140aaf1f32 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c
> @@ -1846,15 +1846,19 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
> timeout = schedule_timeout(timeout);
> lock_sock(sk);
>
> - /* Connection established. Whatever happens to socket once we
> - * release it, that's not connect()'s concern. No need to go
> + /* Connection was established. Whatever happens to socket once
> + * we release it, that's not connect()'s concern. No need to go
> * into signal and timeout handling. Call it a day.
> *
> * Note that allowing to "reset" an already established socket
> * here is racy and insecure.
> */
> - if (sk->sk_state == TCP_ESTABLISHED)
> - break;
> + if (sk->sk_state == TCP_ESTABLISHED ||
> + sk->sk_state == TCP_CLOSING) {
> + err = 0;
> + finish_wait(sk_sleep(sk), &wait);
> + goto out;
> + }
[Severity: Low]
This isn't a bug, but the new short circuit lists only TCP_ESTABLISHED and
TCP_CLOSING as "once established", while an established socket can also be
taken straight to TCP_CLOSE by a transport event while connect() is
scheduled out:
net/vmw_vsock/vmci_transport.c:vmci_transport_handle_detach() {
...
sk->sk_state = TCP_CLOSE;
}
sk->sk_state_change(sk);
}
net/vmw_vsock/virtio_transport.c:virtio_vsock_reset_sock() {
sk->sk_state = TCP_CLOSE;
sk->sk_err = ECONNRESET;
sk_error_report(sk);
}
Those sockets were established as well, but they miss this check, so
connect() still returns -ECONNRESET or -ETIMEDOUT for them.
The cleanup side of that case is covered by the follow-up patch in this
series, "vsock: handle socket bricking due to transport event", which adds
an early return to vsock_unconnected_reset() for sock->state ==
SS_CONNECTED or SS_DISCONNECTING, and neither of the two transport paths
above modifies sk->sk_socket->state.
Is the remaining difference in the connect() return value for the TCP_CLOSE
case the intended behaviour?
>
> /* If connection was _not_ established and a signal/timeout came
> * to be, we want the socket's state reset. We keep the binding.
> @@ -1877,8 +1881,7 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
> out_wait:
> finish_wait(sk_sleep(sk), &wait);
> out_reset:
> - if (err)
> - vsock_unconnected_reset(sk);
> + vsock_unconnected_reset(sk);
[Severity: High]
With this call now unconditional, can a VMCI detach during the handshake
turn this cleanup into a silent no-op plus a warning backtrace?
vmci_transport_handle_detach() sets the flags before it inspects sk_state,
and it explicitly handles the TCP_SYN_SENT case:
net/vmw_vsock/vmci_transport.c:vmci_transport_handle_detach() {
...
sock_set_flag(sk, SOCK_DONE);
...
WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
...
if (sk->sk_state == TCP_SYN_SENT) {
sk->sk_state = TCP_CLOSE;
sk->sk_err = ECONNRESET;
sk_error_report(sk);
return;
}
}
The valid qp_handle that this path requires is already installed while the
client socket is still TCP_SYN_SENT, by
vmci_transport_recv_connecting_client_negotiate(), which also subscribes
detach_sub_id; TCP_ESTABLISHED is only set later on ATTACH. The detach
callback runs under bh_lock_sock() while blocking connect() has dropped the
socket lock in release_sock()/schedule_timeout().
The woken connect() then sees sk_state == TCP_CLOSE, so the new
ESTABLISHED/TCP_CLOSING short circuit above does not apply, it leaves the
loop on sk_err != 0, takes err = sock_error(sk) and reaches
vsock_unconnected_reset(), where the first check fires and returns:
net/vmw_vsock/af_vsock.c:vsock_unconnected_reset() {
if (WARN_ON_ONCE(vsk->peer_shutdown) ||
WARN_ON_ONCE(sock_flag(sk, SOCK_DONE)) ||
WARN_ON_ONCE(sk->sk_state != TCP_SYN_SENT &&
sk->sk_state != TCP_CLOSE))
return;
...
}
That skips vsock_transport_cancel_pkt(), vsock_deassign_transport(), the
WRITE_ONCE(sk->sk_state, TCP_CLOSE) and sk->sk_socket->state =
SS_UNCONNECTED.
Does that leave the socket with its transport still assigned and
sock->state stuck at SS_CONNECTING, so later connect() attempts return
-EALREADY for O_NONBLOCK, or re-enter the loop, burn the full
vsk->connect_timeout and return -ETIMEDOUT?
Before this series the same path simply did sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED; with no warning, and the socket stayed
retryable. At the end of the series the new SS_CONNECTED/SS_DISCONNECTING
early return in vsock_unconnected_reset() does not cover this case, since
sock->state is SS_CONNECTING here and sk_state is TCP_CLOSE, so the
WARN_ON_ONCE(vsk->peer_shutdown) check is still the one that fires.
> out:
> release_sock(sk);
> return err;
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260922-vsock-connect-reset-closing-v3-0-78907b8200d4%40rbox.co
next prev parent reply other threads:[~2026-09-24 13:15 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 13:14 [PATCH net v3 0/8] vsock: fix connect() races Michal Luczaj
2026-09-22 13:14 ` [PATCH net v3 1/8] vhost/vsock: Fix socket state constant Michal Luczaj
2026-09-22 13:14 ` [PATCH net v3 2/8] vsock: simplify error check condition Michal Luczaj
2026-09-22 13:14 ` [PATCH net v3 3/8] vsock: do not preserve transport assignment Michal Luczaj
2026-09-24 13:15 ` netdev-bot+sashiko
2026-09-24 21:27 ` Michal Luczaj
2026-09-22 13:14 ` [PATCH net v3 4/8] vsock: drop the re-assignment logic Michal Luczaj
2026-09-24 13:15 ` netdev-bot+sashiko
2026-09-24 21:27 ` Michal Luczaj
2026-09-22 13:14 ` [PATCH net v3 5/8] vsock: treat TCP_CLOSING as once-established Michal Luczaj
2026-09-24 13:15 ` netdev-bot+sashiko [this message]
2026-09-24 21:27 ` Michal Luczaj
2026-09-22 13:15 ` [PATCH net v3 6/8] vsock: handle socket bricking due to transport event Michal Luczaj
2026-09-24 13:15 ` netdev-bot+sashiko
2026-09-24 21:28 ` Michal Luczaj
2026-09-22 13:15 ` [PATCH net v3 7/8] vsock: handle listen() racing connect() Michal Luczaj
2026-09-24 13:15 ` netdev-bot+sashiko
2026-09-24 21:28 ` Michal Luczaj
2026-09-22 13:15 ` [PATCH net v3 8/8] vsock: enforce no-transport invariant for TCP_LISTEN sockets 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=179025570581.2160803.6664724141686428896@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=eperezma@redhat.com \
--cc=horms@kernel.org \
--cc=imv4bel@gmail.com \
--cc=jasowangio@gmail.com \
--cc=kuba@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--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 \
--cc=xuanzhuo@linux.alibaba.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®