diff mbox series

[v3] vsock: each transport cycles only on its own sockets

Message ID 20220310135012.175219-1-jiyong@google.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [v3] vsock: each transport cycles only on its own sockets | expand

Checks

Context Check Description
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Jiyong Park March 10, 2022, 1:50 p.m. UTC
When iterating over sockets using vsock_for_each_connected_socket, make
sure that a transport filters out sockets that don't belong to the
transport.

There actually was an issue caused by this; in a nested VM
configuration, destroying the nested VM (which often involves the
closing of /dev/vhost-vsock if there was h2g connections to the nested
VM) kills not only the h2g connections, but also all existing g2h
connections to the (outmost) host which are totally unrelated.

Tested: Executed the following steps on Cuttlefish (Android running on a
VM) [1]: (1) Enter into an `adb shell` session - to have a g2h
connection inside the VM, (2) open and then close /dev/vhost-vsock by
`exec 3< /dev/vhost-vsock && exec 3<&-`, (3) observe that the adb
session is not reset.

[1] https://android.googlesource.com/device/google/cuttlefish/

Fixes: c0cfa2d8a788 ("vsock: add multi-transports support")
Signed-off-by: Jiyong Park <jiyong@google.com>
---
Changes in v3:
  - Fixed the build error in vmci_transport.c
Changes in v2:
  - Squashed into a single patch

 drivers/vhost/vsock.c            | 3 ++-
 include/net/af_vsock.h           | 3 ++-
 net/vmw_vsock/af_vsock.c         | 9 +++++++--
 net/vmw_vsock/virtio_transport.c | 7 +++++--
 net/vmw_vsock/vmci_transport.c   | 5 ++++-
 5 files changed, 20 insertions(+), 7 deletions(-)


base-commit: 3bf7edc84a9eb4007dd9a0cb8878a7e1d5ec6a3b

Comments

Stefano Garzarella March 10, 2022, 2:14 p.m. UTC | #1
On Thu, Mar 10, 2022 at 10:50:11PM +0900, Jiyong Park wrote:
>When iterating over sockets using vsock_for_each_connected_socket, make
>sure that a transport filters out sockets that don't belong to the
>transport.
>
>There actually was an issue caused by this; in a nested VM
>configuration, destroying the nested VM (which often involves the
>closing of /dev/vhost-vsock if there was h2g connections to the nested
>VM) kills not only the h2g connections, but also all existing g2h
>connections to the (outmost) host which are totally unrelated.
>
>Tested: Executed the following steps on Cuttlefish (Android running on a
>VM) [1]: (1) Enter into an `adb shell` session - to have a g2h
>connection inside the VM, (2) open and then close /dev/vhost-vsock by
>`exec 3< /dev/vhost-vsock && exec 3<&-`, (3) observe that the adb
>session is not reset.
>
>[1] https://android.googlesource.com/device/google/cuttlefish/
>
>Fixes: c0cfa2d8a788 ("vsock: add multi-transports support")
>Signed-off-by: Jiyong Park <jiyong@google.com>
>---
>Changes in v3:
>  - Fixed the build error in vmci_transport.c
>Changes in v2:
>  - Squashed into a single patch
>
> drivers/vhost/vsock.c            | 3 ++-
> include/net/af_vsock.h           | 3 ++-
> net/vmw_vsock/af_vsock.c         | 9 +++++++--
> net/vmw_vsock/virtio_transport.c | 7 +++++--
> net/vmw_vsock/vmci_transport.c   | 5 ++++-
> 5 files changed, 20 insertions(+), 7 deletions(-)

It seems okay now, I ran my test suite and everything seems to be fine:

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>

Thanks,
Stefano
Michael S. Tsirkin March 10, 2022, 3:28 p.m. UTC | #2
On Thu, Mar 10, 2022 at 03:14:20PM +0100, Stefano Garzarella wrote:
> On Thu, Mar 10, 2022 at 10:50:11PM +0900, Jiyong Park wrote:
> > When iterating over sockets using vsock_for_each_connected_socket, make
> > sure that a transport filters out sockets that don't belong to the
> > transport.
> > 
> > There actually was an issue caused by this; in a nested VM
> > configuration, destroying the nested VM (which often involves the
> > closing of /dev/vhost-vsock if there was h2g connections to the nested
> > VM) kills not only the h2g connections, but also all existing g2h
> > connections to the (outmost) host which are totally unrelated.
> > 
> > Tested: Executed the following steps on Cuttlefish (Android running on a
> > VM) [1]: (1) Enter into an `adb shell` session - to have a g2h
> > connection inside the VM, (2) open and then close /dev/vhost-vsock by
> > `exec 3< /dev/vhost-vsock && exec 3<&-`, (3) observe that the adb
> > session is not reset.
> > 
> > [1] https://android.googlesource.com/device/google/cuttlefish/
> > 
> > Fixes: c0cfa2d8a788 ("vsock: add multi-transports support")
> > Signed-off-by: Jiyong Park <jiyong@google.com>
> > ---
> > Changes in v3:
> >  - Fixed the build error in vmci_transport.c
> > Changes in v2:
> >  - Squashed into a single patch
> > 
> > drivers/vhost/vsock.c            | 3 ++-
> > include/net/af_vsock.h           | 3 ++-
> > net/vmw_vsock/af_vsock.c         | 9 +++++++--
> > net/vmw_vsock/virtio_transport.c | 7 +++++--
> > net/vmw_vsock/vmci_transport.c   | 5 ++++-
> > 5 files changed, 20 insertions(+), 7 deletions(-)
> 
> It seems okay now, I ran my test suite and everything seems to be fine:
> 
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> 
> Thanks,
> Stefanoc

Thanks!
Acked-by: Michael S. Tsirkin <mst@redhat.com>

Not a new regression so I think we should take this in the next cycle,
let's be careful here especially since previous version was not even
build-tested by the contributor.
Jakub Kicinski March 11, 2022, 1:08 a.m. UTC | #3
On Thu, 10 Mar 2022 10:28:03 -0500 Michael S. Tsirkin wrote:
> On Thu, Mar 10, 2022 at 03:14:20PM +0100, Stefano Garzarella wrote:
> > On Thu, Mar 10, 2022 at 10:50:11PM +0900, Jiyong Park wrote:  
> > > When iterating over sockets using vsock_for_each_connected_socket, make
> > > sure that a transport filters out sockets that don't belong to the
> > > transport.
> > > 
> > > There actually was an issue caused by this; in a nested VM
> > > configuration, destroying the nested VM (which often involves the
> > > closing of /dev/vhost-vsock if there was h2g connections to the nested
> > > VM) kills not only the h2g connections, but also all existing g2h
> > > connections to the (outmost) host which are totally unrelated.
> > > 
> > > Tested: Executed the following steps on Cuttlefish (Android running on a
> > > VM) [1]: (1) Enter into an `adb shell` session - to have a g2h
> > > connection inside the VM, (2) open and then close /dev/vhost-vsock by
> > > `exec 3< /dev/vhost-vsock && exec 3<&-`, (3) observe that the adb
> > > session is not reset.
> > > 
> > > [1] https://android.googlesource.com/device/google/cuttlefish/
> > > 
> > > Fixes: c0cfa2d8a788 ("vsock: add multi-transports support")
> > > Signed-off-by: Jiyong Park <jiyong@google.com>
> > > ---
> > > Changes in v3:
> > >  - Fixed the build error in vmci_transport.c
> > > Changes in v2:
> > >  - Squashed into a single patch
> > > 
> > > drivers/vhost/vsock.c            | 3 ++-
> > > include/net/af_vsock.h           | 3 ++-
> > > net/vmw_vsock/af_vsock.c         | 9 +++++++--
> > > net/vmw_vsock/virtio_transport.c | 7 +++++--
> > > net/vmw_vsock/vmci_transport.c   | 5 ++++-
> > > 5 files changed, 20 insertions(+), 7 deletions(-)  
> > 
> > It seems okay now, I ran my test suite and everything seems to be fine:
> > 
> > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> 
> Thanks!
> Acked-by: Michael S. Tsirkin <mst@redhat.com>
> 
> Not a new regression so I think we should take this in the next cycle,
> let's be careful here especially since previous version was not even
> build-tested by the contributor.

Ack, our build bot ignored it as well :( 

Jiyong, would you mind collecting the tags from Stefano and Michael 
and reposting? I fixed our build bot, it should build test the patch
- I can't re-run on an already ignored patch, sadly.
Jiyong Park March 11, 2022, 1:26 a.m. UTC | #4
First of all, sorry for the stupid breakage I made in V2. I forgot to turn
CONFIG_VMWARE_VMCI_VSOCKETS on when I did the build by
myself. I turned it on later and fixed the build error in V3.

> Jiyong, would you mind collecting the tags from Stefano and Michael
> and reposting? I fixed our build bot, it should build test the patch
> - I can't re-run on an already ignored patch, sadly.

Jakub, please bear with me; Could you explain what you exactly want
me to do? I'm new to kernel development and don't know how changes
which Stefano and Machael maintain get tested and staged.
Jakub Kicinski March 11, 2022, 1:50 a.m. UTC | #5
On Fri, 11 Mar 2022 10:26:08 +0900 Jiyong Park wrote:
> First of all, sorry for the stupid breakage I made in V2. I forgot to turn
> CONFIG_VMWARE_VMCI_VSOCKETS on when I did the build by
> myself. I turned it on later and fixed the build error in V3.
> 
> > Jiyong, would you mind collecting the tags from Stefano and Michael
> > and reposting? I fixed our build bot, it should build test the patch
> > - I can't re-run on an already ignored patch, sadly.  
> 
> Jakub, please bear with me; Could you explain what you exactly want
> me to do? I'm new to kernel development and don't know how changes
> which Stefano and Machael maintain get tested and staged.

I was just asking to send the same patch (v3) second time to kick off
a CI. You can change the subject prefix to "[PATCH net v3 resend]".
And add

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>

between the "Fixes:" and your "Signed-off-by:" tag, since the code will
be identical.

The CI didn't catch v3 because I fumbled patch filtering config.
Your posting was correct, it was entirely my error.
diff mbox series

Patch

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 37f0b4274113..e6c9d41db1de 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -753,7 +753,8 @@  static int vhost_vsock_dev_release(struct inode *inode, struct file *file)
 
 	/* Iterating over all connections for all CIDs to find orphans is
 	 * inefficient.  Room for improvement here. */
-	vsock_for_each_connected_socket(vhost_vsock_reset_orphans);
+	vsock_for_each_connected_socket(&vhost_transport.transport,
+					vhost_vsock_reset_orphans);
 
 	/* Don't check the owner, because we are in the release path, so we
 	 * need to stop the vsock device in any case.
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index ab207677e0a8..f742e50207fb 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -205,7 +205,8 @@  struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr);
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
 					 struct sockaddr_vm *dst);
 void vsock_remove_sock(struct vsock_sock *vsk);
-void vsock_for_each_connected_socket(void (*fn)(struct sock *sk));
+void vsock_for_each_connected_socket(struct vsock_transport *transport,
+				     void (*fn)(struct sock *sk));
 int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk);
 bool vsock_find_cid(unsigned int cid);
 
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 38baeb189d4e..f04abf662ec6 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -334,7 +334,8 @@  void vsock_remove_sock(struct vsock_sock *vsk)
 }
 EXPORT_SYMBOL_GPL(vsock_remove_sock);
 
-void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
+void vsock_for_each_connected_socket(struct vsock_transport *transport,
+				     void (*fn)(struct sock *sk))
 {
 	int i;
 
@@ -343,8 +344,12 @@  void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
 	for (i = 0; i < ARRAY_SIZE(vsock_connected_table); i++) {
 		struct vsock_sock *vsk;
 		list_for_each_entry(vsk, &vsock_connected_table[i],
-				    connected_table)
+				    connected_table) {
+			if (vsk->transport != transport)
+				continue;
+
 			fn(sk_vsock(vsk));
+		}
 	}
 
 	spin_unlock_bh(&vsock_table_lock);
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index fb3302fff627..5afc194a58bb 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -24,6 +24,7 @@ 
 static struct workqueue_struct *virtio_vsock_workqueue;
 static struct virtio_vsock __rcu *the_virtio_vsock;
 static DEFINE_MUTEX(the_virtio_vsock_mutex); /* protects the_virtio_vsock */
+static struct virtio_transport virtio_transport; /* forward declaration */
 
 struct virtio_vsock {
 	struct virtio_device *vdev;
@@ -384,7 +385,8 @@  static void virtio_vsock_event_handle(struct virtio_vsock *vsock,
 	switch (le32_to_cpu(event->id)) {
 	case VIRTIO_VSOCK_EVENT_TRANSPORT_RESET:
 		virtio_vsock_update_guest_cid(vsock);
-		vsock_for_each_connected_socket(virtio_vsock_reset_sock);
+		vsock_for_each_connected_socket(&virtio_transport.transport,
+						virtio_vsock_reset_sock);
 		break;
 	}
 }
@@ -662,7 +664,8 @@  static void virtio_vsock_remove(struct virtio_device *vdev)
 	synchronize_rcu();
 
 	/* Reset all connected sockets when the device disappear */
-	vsock_for_each_connected_socket(virtio_vsock_reset_sock);
+	vsock_for_each_connected_socket(&virtio_transport.transport,
+					virtio_vsock_reset_sock);
 
 	/* Stop all work handlers to make sure no one is accessing the device,
 	 * so we can safely call virtio_reset_device().
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 7aef34e32bdf..b17dc9745188 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -75,6 +75,8 @@  static u32 vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID;
 
 static int PROTOCOL_OVERRIDE = -1;
 
+static struct vsock_transport vmci_transport; /* forward declaration */
+
 /* Helper function to convert from a VMCI error code to a VSock error code. */
 
 static s32 vmci_transport_error_to_vsock_error(s32 vmci_error)
@@ -882,7 +884,8 @@  static void vmci_transport_qp_resumed_cb(u32 sub_id,
 					 const struct vmci_event_data *e_data,
 					 void *client_data)
 {
-	vsock_for_each_connected_socket(vmci_transport_handle_detach);
+	vsock_for_each_connected_socket(&vmci_transport,
+					vmci_transport_handle_detach);
 }
 
 static void vmci_transport_recv_pkt_work(struct work_struct *work)