All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Bobby Eshleman" <bobbyeshleman@meta.com>
Cc: virtualization@lists.linux.dev, kvm@vger.kernel.org,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Eugenio Perez" <eperezma@redhat.com>
Subject: Re: [PATCH net-next v5 4/7] vsock: add a netlink command to assign the g2h device to a netns
Date: Thu, 05 Nov 2026 01:54:39 +0000	[thread overview]
Message-ID: <sashiko-outbox-198420@kernel.org> (raw)
In-Reply-To: <20261103-vsock-guest-ns-v5-4-48179b9b66b8@meta.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] vsock: connect() corrupts state and bytes_unsent on swept established socket
--

commit 1f8c2b3f7e5cf0bf0bba26600e236377dd6b1fe3
Author: Bobby Eshleman <bobbyeshleman@meta.com>

vsock: add a netlink command to assign the g2h device to a netns

This commit introduces a vsock generic netlink family with
VSOCK_CMD_DEV_NETNS_SET and VSOCK_CMD_DEV_NETNS_GET to assign the
guest-to-host vsock device to a network namespace and query its assignment.
Sockets that can no longer reach the device after an assignment are closed
with ECONNRESET.

Link: https://lore.kernel.org/all/20200427142518.uwssa6dtasrp3bfc@steredhat/

> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> index c9b28e34b1b3c..7140a3c708389 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c

[ ... ]

> @@ -742,8 +868,269 @@ bool vsock_find_cid(unsigned int cid)

[ ... ]

> +/* Close every connected socket of @t that can no longer reach the g2h device.
> + */
> +static void vsock_g2h_reset_unreachable(const struct vsock_transport *t)
> +{
> +	struct vsock_sock *vsk;
> +	unsigned int i = 0;
> +	struct sock *sk;
> +	bool reset;
> +
> +	lockdep_assert_held(&vsock_g2h_assign_mutex);
> +	lockdep_assert_not_held(&vsock_register_mutex);
> +
> +	/* lock_sock() cannot be taken under vsock_table_lock, so pick the
> +	 * sockets one at a time, then recheck each under both locks.
> +	 */
> +	while ((sk = vsock_next_connected_socket(t, &i,
> +						 vsock_g2h_should_reset))) {
> +		vsk = vsock_sk(sk);
> +
> +		lock_sock(sk);
> +
> +		reset = false;
> +		spin_lock_bh(&vsock_table_lock);
> +		/* It may have been closed since we dropped the table lock. */
> +		if (__vsock_in_connected_table(vsk) && vsk->transport == t &&
> +		    vsock_g2h_should_reset(vsk)) {
> +			__vsock_remove_connected(vsk);
> +			reset = true;
> +		}
> +		spin_unlock_bh(&vsock_table_lock);
> +
> +		if (reset) {
> +			sock_set_flag(sk, SOCK_DONE);
> +			WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
> +			sk->sk_state = TCP_CLOSE;
> +			sk->sk_err = ECONNRESET;
> +			sk_error_report(sk);
> +		}
> +
> +		release_sock(sk);
> +		sock_put(sk);
> +	}
> +}

[ ... ]

> @@ -1705,6 +2093,16 @@ static void vsock_connect_timeout(struct work_struct *work)
>  	sock_put(sk);
>  }
>  
> +/* Avoid breaking the socket when another thread has changed its sock->state
> + * while we were asleep.
> + */
> +static void vsock_connect_close(struct socket *sock)
> +{
> +	sock->sk->sk_state = TCP_CLOSE;
> +	if (sock->state == SS_CONNECTING)
> +		sock->state = SS_UNCONNECTED;
> +}
> +
>  static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
>  			 int addr_len, int flags)
>  {
> @@ -1863,8 +2261,7 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
>  			 * sk_state == TCP_SYN_SENT, which hereby we break.
>  			 * In such case VIRTIO_VSOCK_OP_RST will follow.
>  			 */
> -			sk->sk_state = TCP_CLOSE;
> -			sock->state = SS_UNCONNECTED;
> +			vsock_connect_close(sock);
>  
>  			/* Try to cancel VIRTIO_VSOCK_OP_REQUEST skb sent out by
>  			 * transport->connect().
> @@ -1878,10 +2275,8 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
>  	}
>  
>  	err = sock_error(sk);
> -	if (err) {
> -		sk->sk_state = TCP_CLOSE;
> -		sock->state = SS_UNCONNECTED;
> -	}
> +	if (err)
> +		vsock_connect_close(sock);

[Severity: Medium]
What happens in vsock_connect() when a socket reaches TCP_ESTABLISHED while
sleeping in schedule_timeout(), and is then swept by
vsock_g2h_reset_unreachable() before vsock_connect() reacquires
lock_sock(sk)?

While vsock_connect() has released lock_sock(sk) in schedule_timeout(),
virtio_transport_recv_connecting() can receive VIRTIO_VSOCK_OP_RESPONSE,
transition sk->sk_state to TCP_ESTABLISHED, set sock->state to SS_CONNECTED,
and insert vsk into vsock_connected_table. Once established, a concurrent
vsock_connectible_sendmsg() on another thread can acquire credits via
virtio_transport_get_credit() (incrementing vvs->bytes_unsent) and enqueue
VIRTIO_VSOCK_OP_RW skbs onto send_pkt_queue.

If VSOCK_CMD_DEV_NETNS_SET then runs vsock_g2h_reset_unreachable() before
vsock_connect() reacquires lock_sock(sk), it sets sk->sk_state to TCP_CLOSE
and sk->sk_err to ECONNRESET while leaving sock->state as SS_CONNECTED. When
vsock_connect() wakes up, the once-established check:

	if (sk->sk_state == TCP_ESTABLISHED ||
	    sk->sk_state == TCP_CLOSING) {
		err = 0;
		goto out_wait;
	}

does not match because sk->sk_state is TCP_CLOSE rather than TCP_CLOSING (unlike
virtio_transport_do_close()) and sock->state == SS_CONNECTED is not checked.

If signal_pending(current) || timeout == 0 holds, vsock_connect() proceeds to
call vsock_transport_cancel_pkt(vsk) -> virtio_transport_purge_skbs(), which
purges the post-connection VIRTIO_VSOCK_OP_RW skbs without calling
virtio_transport_consume_skb_sent() to decrement vvs->bytes_unsent. Doesn't
this leak vvs->bytes_unsent and cause vsock_linger() on close() to block until
sk_lingertime expires, similar to the issue fixed by commit 002541ef650b
("vsock: Do not allow signal/timeout on established sockets")?

And if no signal or timeout is pending, vsock_connect() exits the wait loop,
consumes sk->sk_err via sock_error(sk), calls vsock_connect_close(sock), and
returns -ECONNRESET while leaving sock->state as SS_CONNECTED with sk->sk_err
cleared to 0.

Should vsock_g2h_reset_unreachable() set sk->sk_state = TCP_CLOSING like
virtio_transport_do_close(), or should vsock_connect() also check for
sock->state == SS_CONNECTED after schedule_timeout()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103-vsock-guest-ns-v5-0-48179b9b66b8@meta.com?part=4

  reply	other threads:[~2026-11-05  1:54 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04  1:53 [PATCH net-next v5 0/7] vsock: assign the guest vsock device to a network namespace Bobby Eshleman
2026-11-04  1:53 ` [PATCH net-next v5 1/7] vsock: constify the transport in vsock_for_each_connected_socket() Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot
2026-11-04  1:53 ` [PATCH net-next v5 2/7] vsock: rename the vsock pernet operations Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot
2026-11-04  1:53 ` [PATCH net-next v5 3/7] vsock: pass the netns to ->has_remote_cid() Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot
2026-11-04  1:53 ` [PATCH net-next v5 4/7] vsock: add a netlink command to assign the g2h device to a netns Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot [this message]
2026-11-12 19:20     ` Bobby Eshleman
2026-11-12 10:34   ` Michal Luczaj
2026-11-12 19:19     ` Bobby Eshleman
2026-11-04  1:53 ` [PATCH net-next v5 5/7] vsock/virtio: support guest device network namespace Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot
2026-11-10 10:40   ` Paolo Abeni
2026-11-04  1:53 ` [PATCH net-next v5 6/7] selftests/vsock: test the guest vsock " Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot
2026-11-04  1:53 ` [PATCH net-next v5 7/7] selftests/vsock: test the netns assign privilege checks Bobby Eshleman
2026-11-05  1:54   ` sashiko-bot

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=sashiko-outbox-198420@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bobbyeshleman@meta.com \
    --cc=eperezma@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --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.