mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: bobbyeshleman@gmail.com
Cc: sgarzare@redhat.com, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
	corbet@lwn.net, skhan@linuxfoundation.org, stefanha@redhat.com,
	mst@redhat.com, jasowangio@gmail.com, xuanzhuo@linux.alibaba.com,
	eperezma@redhat.com, shuah@kernel.org, rdunlap@infradead.org,
	donald.hunter@gmail.com, virtualization@lists.linux.dev,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org, kvm@vger.kernel.org,
	linux-kselftest@vger.kernel.org, sargun@sargun.me,
	jlinbox@meta.com, sdf.kernel@gmail.com, bobbyeshleman@meta.com
Subject: Re: [PATCH net-next v2 4/6] vsock/virtio: support guest device network namespace
Date: Wed, 23 Sep 2026 19:21:03 +0000	[thread overview]
Message-ID: <179019126374.2160803.9294641399796135651@kernel.org> (raw)
In-Reply-To: <20260921-vsock-guest-ns-v2-4-693bd78fde9e@meta.com>

Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 2 · 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).

- [Medium] virtio_transport_rx_work() samples the g2h namespace once per
  work invocation (`net = vsock_g2h_net_get()` at…
- [Medium] By setting `.netns_assign_allow = true` and `.reset =
  virtio_transport_reset` (net/vmw_vsock/virtio_transport.c:590-591)…
- [Low] virtio_transport_reset_no_sock() is promoted to an exported
  cross-module API (declared in include/linux/virtio_vsock.h,…

--

vsock/virtio: support guest device network namespace

This makes the virtio-vsock guest device assignable to a network namespace
and initializes it to init_net.  The RX work now looks up the currently
assigned namespace and resets received packets while no valid namespace is
available, and new connected sockets are inserted via the new
vsock_maybe_set_connected() helper so insertion is atomic with respect to
namespace assignment.

A few questions below.

> diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
> index f91704731057e..5d15b6d6bdf7f 100644
> --- a/include/linux/virtio_vsock.h
> +++ b/include/linux/virtio_vsock.h
> @@ -286,6 +286,9 @@ void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct sk_buff *
>  u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted);
>  void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit);
>  void virtio_transport_deliver_tap_pkt(struct sk_buff *skb);
> +int virtio_transport_reset(struct vsock_sock *vsk, struct sk_buff *skb);
> +int virtio_transport_reset_no_sock(const struct virtio_transport *t,
> +				   struct sk_buff *skb, struct net *net);
>  int virtio_transport_purge_skbs(void *vsk, struct sk_buff_head *list);
>  int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t read_actor);
>  int virtio_transport_notify_set_rcvlowat(struct vsock_sock *vsk, int val);
> diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
> index 4f9aa9c4c3aa5..5ad93af4bd2b1 100644
> --- a/net/vmw_vsock/virtio_transport.c
> +++ b/net/vmw_vsock/virtio_transport.c

[ ... ]

> @@ -587,6 +587,8 @@ static struct virtio_transport virtio_transport = {
>  		.seqpacket_has_data       = virtio_transport_seqpacket_has_data,
>  
>  		.msgzerocopy_allow        = virtio_transport_msgzerocopy_allow,
> +		.netns_assign_allow       = true,
> +		.reset                    = virtio_transport_reset,

[Severity: Medium]

Setting .netns_assign_allow = true makes vsock_netns_assignable() true for
the g2h transport, which activates the reset sweep in
vsock_g2h_reset_unreachable().  That sweep calls t->reset() while holding
only vsock_register_mutex and a socket reference, never lock_sock(sk):

net/vmw_vsock/af_vsock.c:vsock_g2h_reset_unreachable() {
	...
		sk->sk_state = TCP_CLOSE;
		sk->sk_err = ECONNRESET;
		sk_error_report(sk);
	...
	list_for_each_entry_safe(vsk, tmp, &reset_list, pending_reset) {
		list_del_init(&vsk->pending_reset);
		t->reset(vsk, NULL);
	...
}

virtio_transport_reset() -> virtio_transport_send_pkt_info() addresses the
RST straight out of the socket:

	if (!info->remote_cid) {
		dst_cid	= vsk->remote_addr.svm_cid;
		dst_port = vsk->remote_addr.svm_port;

Those fields are normally only stable under lock_sock(sk).

The sk_error_report() above wakes a blocking connect(), which then runs:

net/vmw_vsock/af_vsock.c:vsock_connect() {
	err = sock_error(sk);
	if (err) {
		sk->sk_state = TCP_CLOSE;
		sock->state = SS_UNCONNECTED;
	}
}

and returns -ECONNRESET.  If userspace retries connect() immediately, the

	memcpy(&vsk->remote_addr, remote_addr,
	       sizeof(vsk->remote_addr));

in vsock_connect() runs before vsock_assign_transport() blocks on
vsock_register_mutex, so it is not serialized against the sweep that is
still walking reset_list.

Can the sweep then read the freshly overwritten remote_addr and send the
RST to the new destination, so the actual peer of the connection that was
just torn down never gets a reset and waits for a timeout instead?

>  
>  		.notify_poll_in           = virtio_transport_notify_poll_in,
>  		.notify_poll_out          = virtio_transport_notify_poll_out,

[ ... ]

> @@ -633,7 +635,11 @@ static void virtio_transport_rx_work(struct work_struct *work)
>  {
>  	struct virtio_vsock *vsock =
>  		container_of(work, struct virtio_vsock, rx_work);
> +	struct virtio_transport *t = &virtio_transport;
>  	struct virtqueue *vq;
> +	struct net *net;
> +
> +	net = vsock_g2h_net_get();
>  
>  	mutex_lock(&vsock->rx_lock);
>  
> @@ -682,10 +688,14 @@ static void virtio_transport_rx_work(struct work_struct *work)
>  
>  			virtio_transport_deliver_tap_pkt(skb);
>  
> -			/* Force virtio-transport into global mode since it
> -			 * does not yet support local-mode namespacing.
> -			 */
> -			virtio_transport_recv_pkt(&virtio_transport, skb, NULL);
> +			/* The virtio send path does not use @net. */
> +			if (unlikely(!net)) {
> +				virtio_transport_reset_no_sock(t, skb, NULL);
> +				kfree_skb(skb);
> +				continue;
> +			}
> +
> +			virtio_transport_recv_pkt(t, skb, net);

[Severity: Medium]

The namespace is sampled once per work invocation and then pinned with a
hard reference for the whole drain loop:

	net = vsock_g2h_net_get();
	...
	do {
		...
			virtio_transport_recv_pkt(t, skb, net);
	} while (!virtqueue_enable_cb(vq));

Meanwhile the assign path publishes the new namespace and then sweeps the
connected table:

net/vmw_vsock/af_vsock.c:vsock_g2h_net_assign() {
	...
	rcu_assign_pointer(vsock_g2h_net, net);
	vsock_g2h_reset_unreachable(transport_g2h);
	...
}

As soon as the new pointer is published, a connect() from the newly
assigned namespace is permitted, because vsock_assign_transport() consults
vsock_g2h_net_reachable() which already reads it.  If the host RESPONSE for
that connection is drained by the batch still holding the previous
namespace, vsock_find_connected_socket_net(&src, &dst, net) does not find
the socket (vsock_net_check_mode() of the local-mode new net against the
old net is false), so virtio_transport_recv_pkt() falls into

	(void)virtio_transport_reset_no_sock(t, skb, net);

and the just-established connection is reset.  Is that acceptable for the
remainder of an in-flight batch, or should the namespace be re-read per
packet?

In the other direction, between the rcu_assign_pointer() above and the
per-socket store in vsock_g2h_reset_unreachable():

		sk->sk_state = TCP_CLOSE;
		sk->sk_err = ECONNRESET;

can the in-flight batch still resolve packets against the old namespace and
deliver payload plus credit updates into sockets that the device no longer
belongs to?

The commit message describes the batch granularity only for the dying
namespace case:

  "received packets are reset until a new valid namespace has been assigned
   and/or automatically returned to, and the next RX batch begins"

Should it also describe what happens to packets of the newly assigned
namespace while an older batch is still draining?

>  		}
>  	} while (!virtqueue_enable_cb(vq));
>  

[ ... ]

> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index f225f53ed4bab..c24049b2a3866 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c

[ ... ]

> @@ -1315,8 +1315,8 @@ static int virtio_transport_reset(struct vsock_sock *vsk,
>   * loopback, this is the namespace of the socket. For vhost, this is the
>   * namespace of the VM (i.e., vhost_vsock).
>   */
> -static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
> -					  struct sk_buff *skb, struct net *net)
> +int virtio_transport_reset_no_sock(const struct virtio_transport *t,
> +				   struct sk_buff *skb, struct net *net)

[Severity: Low]

This isn't a bug, but the comment above still enumerates only the loopback
and vhost meanings of @net, while the helper is now exported via
include/linux/virtio_vsock.h and the new caller in
virtio_transport_rx_work() passes NULL.  Whether NULL is fine depends on
the ->send_pkt behind @t: virtio_transport_send_pkt() ignores @net, and
vhost_transport_send_pkt() passes it to vhost_vsock_get() ->
vsock_net_check_mode(), which treats NULL as VSOCK_NET_MODE_GLOBAL.  Could
the comment be extended to say that NULL is permitted and what it means?

>  {
>  	struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb);
>  	struct virtio_vsock_pkt_info info = {
> @@ -1355,6 +1355,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
>  
>  	return t->send_pkt(reply, net);
>  }
> +EXPORT_SYMBOL_GPL(virtio_transport_reset_no_sock);

[ ... ]

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260921-vsock-guest-ns-v2-0-693bd78fde9e%40meta.com

  reply	other threads:[~2026-09-23 19:21 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-22  1:18 [PATCH net-next v2 0/6] vsock: assign the guest vsock device to a " Bobby Eshleman
2026-09-22  1:18 ` [PATCH net-next v2 1/6] vsock: constify the transport in vsock_for_each_connected_socket() Bobby Eshleman
2026-09-22  1:18 ` [PATCH net-next v2 2/6] vsock: rename the vsock pernet operations Bobby Eshleman
2026-09-22  1:18 ` [PATCH net-next v2 3/6] vsock: add a netlink command to assign the g2h device to a netns Bobby Eshleman
2026-09-23 19:21   ` netdev-bot+sashiko
2026-09-24 22:40     ` Bobby Eshleman
2026-09-22  1:18 ` [PATCH net-next v2 4/6] vsock/virtio: support guest device network namespace Bobby Eshleman
2026-09-23 19:21   ` netdev-bot+sashiko [this message]
2026-09-24  1:16     ` Bobby Eshleman
2026-09-22  1:18 ` [PATCH net-next v2 5/6] selftests/vsock: test the guest vsock " Bobby Eshleman
2026-09-23 19:21   ` netdev-bot+sashiko
2026-09-24  0:42     ` Bobby Eshleman
2026-09-22  1:18 ` [PATCH net-next v2 6/6] selftests/vsock: test the netns assign privilege checks Bobby Eshleman
2026-09-23 19:21   ` netdev-bot+sashiko
2026-09-24  0:24     ` Bobby Eshleman
2026-09-24  0:55       ` Bobby Eshleman

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=179019126374.2160803.9294641399796135651@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=bobbyeshleman@gmail.com \
    --cc=bobbyeshleman@meta.com \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=donald.hunter@gmail.com \
    --cc=edumazet@google.com \
    --cc=eperezma@redhat.com \
    --cc=horms@kernel.org \
    --cc=jasowangio@gmail.com \
    --cc=jlinbox@meta.com \
    --cc=kuba@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=rdunlap@infradead.org \
    --cc=sargun@sargun.me \
    --cc=sdf.kernel@gmail.com \
    --cc=sgarzare@redhat.com \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --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®