--- /dev/null
+From d5afa82c977ea06f7119058fa0eb8519ea501031 Mon Sep 17 00:00:00 2001
+From: Sunil Muthuswamy <sunilmut@microsoft.com>
+Date: Thu, 13 Jun 2019 03:52:27 +0000
+Subject: vsock: correct removal of socket from the list
+
+From: Sunil Muthuswamy <sunilmut@microsoft.com>
+
+commit d5afa82c977ea06f7119058fa0eb8519ea501031 upstream.
+
+The current vsock code for removal of socket from the list is both
+subject to race and inefficient. It takes the lock, checks whether
+the socket is in the list, drops the lock and if the socket was on the
+list, deletes it from the list. This is subject to race because as soon
+as the lock is dropped once it is checked for presence, that condition
+cannot be relied upon for any decision. It is also inefficient because
+if the socket is present in the list, it takes the lock twice.
+
+Signed-off-by: Sunil Muthuswamy <sunilmut@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/vmw_vsock/af_vsock.c | 38 +++++++-------------------------------
+ 1 file changed, 7 insertions(+), 31 deletions(-)
+
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -274,7 +274,8 @@ EXPORT_SYMBOL_GPL(vsock_insert_connected
+ void vsock_remove_bound(struct vsock_sock *vsk)
+ {
+ spin_lock_bh(&vsock_table_lock);
+- __vsock_remove_bound(vsk);
++ if (__vsock_in_bound_table(vsk))
++ __vsock_remove_bound(vsk);
+ spin_unlock_bh(&vsock_table_lock);
+ }
+ EXPORT_SYMBOL_GPL(vsock_remove_bound);
+@@ -282,7 +283,8 @@ EXPORT_SYMBOL_GPL(vsock_remove_bound);
+ void vsock_remove_connected(struct vsock_sock *vsk)
+ {
+ spin_lock_bh(&vsock_table_lock);
+- __vsock_remove_connected(vsk);
++ if (__vsock_in_connected_table(vsk))
++ __vsock_remove_connected(vsk);
+ spin_unlock_bh(&vsock_table_lock);
+ }
+ EXPORT_SYMBOL_GPL(vsock_remove_connected);
+@@ -318,35 +320,10 @@ struct sock *vsock_find_connected_socket
+ }
+ EXPORT_SYMBOL_GPL(vsock_find_connected_socket);
+
+-static bool vsock_in_bound_table(struct vsock_sock *vsk)
+-{
+- bool ret;
+-
+- spin_lock_bh(&vsock_table_lock);
+- ret = __vsock_in_bound_table(vsk);
+- spin_unlock_bh(&vsock_table_lock);
+-
+- return ret;
+-}
+-
+-static bool vsock_in_connected_table(struct vsock_sock *vsk)
+-{
+- bool ret;
+-
+- spin_lock_bh(&vsock_table_lock);
+- ret = __vsock_in_connected_table(vsk);
+- spin_unlock_bh(&vsock_table_lock);
+-
+- return ret;
+-}
+-
+ void vsock_remove_sock(struct vsock_sock *vsk)
+ {
+- if (vsock_in_bound_table(vsk))
+- vsock_remove_bound(vsk);
+-
+- if (vsock_in_connected_table(vsk))
+- vsock_remove_connected(vsk);
++ vsock_remove_bound(vsk);
++ vsock_remove_connected(vsk);
+ }
+ EXPORT_SYMBOL_GPL(vsock_remove_sock);
+
+@@ -477,8 +454,7 @@ static void vsock_pending_work(struct wo
+ * incoming packets can't find this socket, and to reduce the reference
+ * count.
+ */
+- if (vsock_in_connected_table(vsk))
+- vsock_remove_connected(vsk);
++ vsock_remove_connected(vsk);
+
+ sk->sk_state = TCP_CLOSE;
+