Skip to content

Commit ac79b1d

Browse files
stefano-garzarellagregkh
authored andcommitted
vsock: fix locking in vsock_shutdown()
commit 1c5fae9 upstream. In vsock_shutdown() we touched some socket fields without holding the socket lock, such as 'state' and 'sk_flags'. Also, after the introduction of multi-transport, we are accessing 'vsk->transport' in vsock_send_shutdown() without holding the lock and this call can be made while the connection is in progress, so the transport can change in the meantime. To avoid issues, we hold the socket lock when we enter in vsock_shutdown() and release it when we leave. Among the transports that implement the 'shutdown' callback, only hyperv_transport acquired the lock. Since the caller now holds it, we no longer take it. Fixes: d021c34 ("VSOCK: Introduce VM Sockets") Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c025081 commit ac79b1d

2 files changed

Lines changed: 5 additions & 7 deletions

File tree

net/vmw_vsock/af_vsock.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,10 +808,12 @@ static int vsock_shutdown(struct socket *sock, int mode)
808808
*/
809809

810810
sk = sock->sk;
811+
812+
lock_sock(sk);
811813
if (sock->state == SS_UNCONNECTED) {
812814
err = -ENOTCONN;
813815
if (sk->sk_type == SOCK_STREAM)
814-
return err;
816+
goto out;
815817
} else {
816818
sock->state = SS_DISCONNECTING;
817819
err = 0;
@@ -820,17 +822,17 @@ static int vsock_shutdown(struct socket *sock, int mode)
820822
/* Receive and send shutdowns are treated alike. */
821823
mode = mode & (RCV_SHUTDOWN | SEND_SHUTDOWN);
822824
if (mode) {
823-
lock_sock(sk);
824825
sk->sk_shutdown |= mode;
825826
sk->sk_state_change(sk);
826-
release_sock(sk);
827827

828828
if (sk->sk_type == SOCK_STREAM) {
829829
sock_reset_flag(sk, SOCK_DONE);
830830
vsock_send_shutdown(sk, mode);
831831
}
832832
}
833833

834+
out:
835+
release_sock(sk);
834836
return err;
835837
}
836838

net/vmw_vsock/hyperv_transport.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -464,14 +464,10 @@ static void hvs_shutdown_lock_held(struct hvsock *hvs, int mode)
464464

465465
static int hvs_shutdown(struct vsock_sock *vsk, int mode)
466466
{
467-
struct sock *sk = sk_vsock(vsk);
468-
469467
if (!(mode & SEND_SHUTDOWN))
470468
return 0;
471469

472-
lock_sock(sk);
473470
hvs_shutdown_lock_held(vsk->trans, mode);
474-
release_sock(sk);
475471
return 0;
476472
}
477473

0 commit comments

Comments
 (0)