]> git.baikalelectronics.ru Git - kernel.git/commit
hv_sock: Fix hang when a connection is closed
authorDexuan Cui <decui@microsoft.com>
Wed, 31 Jul 2019 01:25:45 +0000 (01:25 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 3 Aug 2019 00:26:27 +0000 (17:26 -0700)
commitb2ffbc3c606fbb89e998098d55a4d583245e4dc2
tree0b1318ea44c69b0e5e612f4e91c37d2bf9189780
parentb05691a597042b846f557fe2cb0433019c3f8238
hv_sock: Fix hang when a connection is closed

There is a race condition for an established connection that is being closed
by the guest: the refcnt is 4 at the end of hvs_release() (Note: here the
'remove_sock' is false):

1 for the initial value;
1 for the sk being in the bound list;
1 for the sk being in the connected list;
1 for the delayed close_work.

After hvs_release() finishes, __vsock_release() -> sock_put(sk) *may*
decrease the refcnt to 3.

Concurrently, hvs_close_connection() runs in another thread:
  calls vsock_remove_sock() to decrease the refcnt by 2;
  call sock_put() to decrease the refcnt to 0, and free the sk;
  next, the "release_sock(sk)" may hang due to use-after-free.

In the above, after hvs_release() finishes, if hvs_close_connection() runs
faster than "__vsock_release() -> sock_put(sk)", then there is not any issue,
because at the beginning of hvs_close_connection(), the refcnt is still 4.

The issue can be resolved if an extra reference is taken when the
connection is established.

Fixes: 82a41be58cdd ("hv_sock: Add support for delayed close")
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reviewed-by: Sunil Muthuswamy <sunilmut@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/vmw_vsock/hyperv_transport.c