From b7464d4ae561a6a94a8011df1c8224dc71989312 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Thu, 24 Mar 2022 16:18:52 +0900 Subject: [PATCH] BACKPORT: vsock: each transport cycles only on its own sockets This is an KMI-preserving implementation of commit 8e6ed963763fe21429eabfc76c69ce2b0163a3dd upstream. 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 (cherry picked from commit 8e6ed963763fe21429eabfc76c69ce2b0163a3dd) Signed-off-by: Greg Kroah-Hartman Change-Id: I1de1462fdb2a1b3d40c151ecc50c808ced46b5c8 --- drivers/vhost/vsock.c | 4 ++++ net/vmw_vsock/virtio_transport.c | 7 +++++++ net/vmw_vsock/vmci_transport.c | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index d07a20bbc07b..a963a3aad52e 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -726,6 +726,10 @@ static void vhost_vsock_reset_orphans(struct sock *sk) * executing. */ + /* Only handle our own sockets */ + if (vsk->transport != &vhost_transport.transport) + return; + /* If the peer is still valid, no need to reset connection */ if (vhost_vsock_get(vsk->remote_addr.svm_cid)) return; diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index 4f7c99dfd16c..41525ac28906 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; @@ -357,11 +358,17 @@ static void virtio_vsock_event_fill(struct virtio_vsock *vsock) static void virtio_vsock_reset_sock(struct sock *sk) { + struct vsock_sock *vsk = vsock_sk(sk); + /* vmci_transport.c doesn't take sk_lock here either. At least we're * under vsock_table_lock so the sock cannot disappear while we're * executing. */ + /* Only handle our own sockets */ + if (vsk->transport != &virtio_transport.transport) + return; + sk->sk_state = TCP_CLOSE; sk->sk_err = ECONNRESET; sk_error_report(sk); diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 7aef34e32bdf..32efa1353cb2 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) @@ -803,6 +805,11 @@ static void vmci_transport_handle_detach(struct sock *sk) struct vsock_sock *vsk; vsk = vsock_sk(sk); + + /* Only handle our own sockets */ + if (vsk->transport != &vmci_transport) + return; + if (!vmci_handle_is_invalid(vmci_trans(vsk)->qp_handle)) { sock_set_flag(sk, SOCK_DONE);