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, asias@redhat.com,
kvm@vger.kernel.org, virtualization@lists.linux.dev,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net v2 4/5] vsock: Do not reset a TCP_CLOSING socket
Date: Wed, 16 Sep 2026 23:39:17 +0000 [thread overview]
Message-ID: <178960195730.22033.16636722417726715635@kernel.org> (raw)
In-Reply-To: <20260915-vsock-connect-reset-closing-v2-4-a1d9abb472f7@rbox.co>
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 1 · Low: 0 (1)
- [Medium] Undocumented change of connect()'s return value / sk_err
consumption for an already-established socket.
Pre-existing issues:
- [Low] Reported gap (validated as resolved later in this series,
therefore discarded): at this commit vsock_connect() keys its "do not…
--
vsock: Do not reset a TCP_CLOSING socket
This teaches the vsock_connect() wait loop about the TCP_ESTABLISHED ->
TCP_CLOSING transition triggered by VIRTIO_VSOCK_OP_RST, so a socket that
is still linked in vsock_connected_table is not reset behind the receive
path's back. It also rewrites the tail of vsock_connect() and drops a
stale comment.
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 499e902becfad..adf3f018347ea 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c
[ ... ]
> @@ -1834,23 +1833,22 @@ 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;
> + goto out_wait;
> + }
[Severity: Medium]
The old code did a plain break here, so control fell through to the
err = sock_error(sk) tail. Now it jumps straight to out_wait with err = 0.
Combined with the tail change below, does this mean a blocking connect()
that wakes up in TCP_ESTABLISHED with sk_err already set now returns 0
instead of that error, leaving sk_err queued for the next send()/recv()?
That window looks reachable via virtio_transport_recv_connected(), which
runs only for TCP_ESTABLISHED sockets:
net/vmw_vsock/virtio_transport_common.c:virtio_transport_recv_connected() {
case VIRTIO_VSOCK_OP_RW:
if (!virtio_transport_recv_enqueue(vsk, skb)) {
...
(void)virtio_transport_reset(vsk, skb);
virtio_transport_do_close(vsk, true);
sk->sk_err = ENOBUFS;
...
}
and virtio_transport_do_close() only downgrades the state when the receive
queue is empty:
net/vmw_vsock/virtio_transport_common.c:virtio_transport_do_close() {
WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
if (vsock_stream_has_data(vsk) <= 0)
sk->sk_state = TCP_CLOSING;
...
}
In the queue-full case vsock_stream_has_data(vsk) > 0, so sk_state stays
TCP_ESTABLISHED while sk_err == ENOBUFS.
The changelog mentions only the TCP_CLOSING transition plus "Drop the
redundant err=0 and the inaccurate comment above signal_pending()". Could
the changelog also spell out that connect() no longer reports or consumes a
pending sk_err for an established socket? The patch carries a Fixes:
d021c344051a tag, so it is a backport candidate and the user-visible change
of the connect() return value seems worth documenting.
>
> /* 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
> - * vsock_connected_table. We keep the binding and the transport
> - * assigned.
> */
> if (signal_pending(current) || timeout == 0) {
> err = timeout == 0 ? -ETIMEDOUT : sock_intr_errno(timeout);
[ ... ]
> @@ -1874,8 +1872,8 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
> prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
> }
>
> - err = sock_error(sk);
> - if (err) {
> + if (sk->sk_state != TCP_ESTABLISHED && sk->sk_state != TCP_CLOSING) {
> + err = sock_error(sk);
> sk->sk_state = TCP_CLOSE;
> sock->state = SS_UNCONNECTED;
> }
[Severity: Low]
This is a pre-existing issue and not introduced by this patch, but the new
whitelist covers only TCP_ESTABLISHED and TCP_CLOSING. A socket that is
still linked in vsock_connected_table but was moved to TCP_CLOSE by a
lockless event handler still gets reset to SS_UNCONNECTED both here and in
the signal_pending() branch above.
Two writers do that without calling vsock_remove_connected():
net/vmw_vsock/virtio_transport.c:virtio_vsock_reset_sock() {
vsk->peer_shutdown = SHUTDOWN_MASK;
sk->sk_state = TCP_CLOSE;
sk->sk_err = ECONNRESET;
sk_error_report(sk);
}
net/vmw_vsock/vmci_transport.c:vmci_transport_handle_detach() {
WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
...
sk->sk_state = TCP_CLOSE;
}
With sock->state == SS_UNCONNECTED, a retry connect() takes the default:
branch, vsock_assign_transport() returns early because the transport is
unchanged, transport->connect() is re-issued, and the next RESPONSE reaches
__vsock_insert_connected():
net/vmw_vsock/af_vsock.c:__vsock_insert_connected() {
sock_hold(&vsk->sk);
list_add(&vsk->connected_table, list);
}
which is the same list_add double add BUG quoted in the changelog, plus a
leaked struct sock reference.
For the record, this appears to be closed by the next patch in the series,
"vsock: Handle sudden TCP_CLOSE during connect", which adds
/* Virtio/PM events are serviced locklessly. */
if (READ_ONCE(vsk->peer_shutdown)) {
err = -ECONNRESET;
goto out;
}
to the same default: branch, and every writer above sets
peer_shutdown = SHUTDOWN_MASK before moving the socket to TCP_CLOSE, so no
action seems needed on the series as a whole. Would it be worth noting in
this patch's changelog that the TCP_CLOSE variant of the same race is
handled by the following patch?
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260915-vsock-connect-reset-closing-v2-0-a1d9abb472f7%40rbox.co
next prev parent reply other threads:[~2026-09-16 23:39 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 13:15 [PATCH net v2 0/5] vsock: Fix connect() races Michal Luczaj
2026-09-15 13:15 ` [PATCH net v2 1/5] vhost/vsock: Fix socket state constant Michal Luczaj
2026-09-16 12:28 ` Stefano Garzarella
2026-09-16 13:15 ` sashiko-bot
2026-09-15 13:15 ` [PATCH net v2 2/5] vsock/virtio: Streamline socket reset on transport/PM event Michal Luczaj
2026-09-16 12:30 ` Stefano Garzarella
2026-09-22 13:17 ` Michal Luczaj
2026-09-24 10:06 ` Stefano Garzarella
2026-09-24 21:26 ` Michal Luczaj
2026-09-16 13:15 ` sashiko-bot
2026-09-16 23:39 ` netdev-bot+sashiko
2026-09-15 13:15 ` [PATCH net v2 3/5] vsock: Enforce no-transport invariant for TCP_LISTEN sockets Michal Luczaj
2026-09-16 12:30 ` Stefano Garzarella
2026-09-22 13:18 ` Michal Luczaj
2026-09-24 10:17 ` Stefano Garzarella
2026-09-24 21:26 ` Michal Luczaj
2026-09-28 10:31 ` Stefano Garzarella
2026-10-05 7:58 ` Michal Luczaj
2026-09-16 13:15 ` sashiko-bot
2026-09-16 23:39 ` netdev-bot+sashiko
2026-09-15 13:15 ` [PATCH net v2 4/5] vsock: Do not reset a TCP_CLOSING socket Michal Luczaj
2026-09-16 12:30 ` Stefano Garzarella
2026-09-22 13:17 ` Michal Luczaj
2026-09-16 13:16 ` sashiko-bot
2026-09-16 23:39 ` netdev-bot+sashiko [this message]
2026-09-15 13:15 ` [PATCH net v2 5/5] vsock: Handle sudden TCP_CLOSE during connect Michal Luczaj
2026-09-16 12:31 ` Stefano Garzarella
2026-09-22 13:18 ` Michal Luczaj
2026-09-28 10:44 ` Stefano Garzarella
2026-09-16 13:16 ` sashiko-bot
2026-09-16 23:39 ` netdev-bot+sashiko
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=178960195730.22033.16636722417726715635@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=asias@redhat.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=eperezma@redhat.com \
--cc=horms@kernel.org \
--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 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.