Sunil Muthuswamy
2019-Jun-13 03:52 UTC
[PATCH net-next] vsock: correct removal of socket from the list
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 at microsoft.com> --- net/vmw_vsock/af_vsock.c | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index d892000..6f063ed 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -282,7 +282,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); @@ -290,7 +291,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); @@ -326,35 +328,10 @@ struct sock *vsock_find_connected_socket(struct sockaddr_vm *src, } 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); @@ -485,8 +462,7 @@ static void vsock_pending_work(struct work_struct *work) * 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; -- 2.7.4
Stefan Hajnoczi
2019-Jun-13 14:47 UTC
[PATCH net-next] vsock: correct removal of socket from the list
On Thu, Jun 13, 2019 at 03:52:27AM +0000, Sunil Muthuswamy wrote:> 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 at microsoft.com> > --- > net/vmw_vsock/af_vsock.c | 38 +++++++------------------------------- > 1 file changed, 7 insertions(+), 31 deletions(-)Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: not available URL: <http://lists.linuxfoundation.org/pipermail/virtualization/attachments/20190613/a9c10bc6/attachment.sig>
David Miller
2019-Jun-15 02:20 UTC
[PATCH net-next] vsock: correct removal of socket from the list
From: Sunil Muthuswamy <sunilmut at microsoft.com> Date: Thu, 13 Jun 2019 03:52:27 +0000> 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 at microsoft.com>Applied.
Seemingly Similar Threads
- [PATCH net-next] vsock: correct removal of socket from the list
- [RFC 1/6] VSOCK: Introduce vsock_find_unbound_socket and vsock_bind_dgram_generic
- [PATCH] virtio_vsock: Fix race condition in virtio_transport_recv_pkt
- [EXTERNAL] Re: [PATCH RFC v1 08/18] x86/hyperv: handling hypercall page setup for root
- [PATCH 0/1] VM Sockets for Linux upstreaming