Skip to content

Commit

Permalink
hv_sock: add locking in the open/close/release code paths
Browse files Browse the repository at this point in the history
Without the patch, when hvs_open_connection() hasn't completely established
a connection (e.g. it has changed sk->sk_state to SS_CONNECTED, but hasn't
inserted the sock into the connected queue), vsock_stream_connect() may see
the sk_state change and return the connection to the userspace, and next
when the userspace closes the connection quickly, hvs_release() may not see
the connection in the connected queue; finally hvs_open_connection()
inserts the connection into the queue, but we won't be able to purge the
connection for ever.

Signed-off-by: Dexuan Cui <[email protected]>
Cc: K. Y. Srinivasan <[email protected]>
Cc: Haiyang Zhang <[email protected]>
Cc: Stephen Hemminger <[email protected]>
Cc: Vitaly Kuznetsov <[email protected]>
Cc: Cathy Avery <[email protected]>
Cc: Rolf Neugebauer <[email protected]>
Cc: Marcelo Cerri <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
dcui authored and davem330 committed Oct 21, 2017
1 parent 0a90e25 commit b4562ca
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions net/vmw_vsock/hyperv_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,15 @@ static void hvs_close_connection(struct vmbus_channel *chan)
struct sock *sk = get_per_channel_state(chan);
struct vsock_sock *vsk = vsock_sk(sk);

lock_sock(sk);

sk->sk_state = SS_UNCONNECTED;
sock_set_flag(sk, SOCK_DONE);
vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN;

sk->sk_state_change(sk);

release_sock(sk);
}

static void hvs_open_connection(struct vmbus_channel *chan)
Expand Down Expand Up @@ -344,6 +348,8 @@ static void hvs_open_connection(struct vmbus_channel *chan)
if (!sk)
return;

lock_sock(sk);

if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) ||
(!conn_from_host && sk->sk_state != SS_CONNECTING))
goto out;
Expand Down Expand Up @@ -395,9 +401,7 @@ static void hvs_open_connection(struct vmbus_channel *chan)

vsock_insert_connected(vnew);

lock_sock(sk);
vsock_enqueue_accept(sk, new);
release_sock(sk);
} else {
sk->sk_state = SS_CONNECTED;
sk->sk_socket->state = SS_CONNECTED;
Expand All @@ -410,6 +414,8 @@ static void hvs_open_connection(struct vmbus_channel *chan)
out:
/* Release refcnt obtained when we called vsock_find_bound_socket() */
sock_put(sk);

release_sock(sk);
}

static u32 hvs_get_local_cid(void)
Expand Down Expand Up @@ -476,13 +482,21 @@ static int hvs_shutdown(struct vsock_sock *vsk, int mode)

static void hvs_release(struct vsock_sock *vsk)
{
struct sock *sk = sk_vsock(vsk);
struct hvsock *hvs = vsk->trans;
struct vmbus_channel *chan = hvs->chan;
struct vmbus_channel *chan;

lock_sock(sk);

sk->sk_state = SS_DISCONNECTING;
vsock_remove_sock(vsk);

release_sock(sk);

chan = hvs->chan;
if (chan)
hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN);

vsock_remove_sock(vsk);
}

static void hvs_destruct(struct vsock_sock *vsk)
Expand Down

0 comments on commit b4562ca

Please sign in to comment.