Skip to content

Commit 135ffc7

Browse files
mmhalAlexei Starovoitov
authored andcommitted
bpf, vsock: Invoke proto::close on close()
vsock defines a BPF callback to be invoked when close() is called. However, this callback is never actually executed. As a result, a closed vsock socket is not automatically removed from the sockmap/sockhash. Introduce a dummy vsock_close() and make vsock_release() call proto::close. Note: changes in __vsock_release() look messy, but it's only due to indent level reduction and variables xmas tree reorder. Fixes: 634f1a7 ("vsock: support sockmap") Signed-off-by: Michal Luczaj <[email protected]> Reviewed-by: Stefano Garzarella <[email protected]> Reviewed-by: Luigi Leonardi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: John Fastabend <[email protected]>
1 parent 9c2a2a4 commit 135ffc7

File tree

1 file changed

+40
-27
lines changed

1 file changed

+40
-27
lines changed

net/vmw_vsock/af_vsock.c

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,14 @@
117117
static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr);
118118
static void vsock_sk_destruct(struct sock *sk);
119119
static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
120+
static void vsock_close(struct sock *sk, long timeout);
120121

121122
/* Protocol family. */
122123
struct proto vsock_proto = {
123124
.name = "AF_VSOCK",
124125
.owner = THIS_MODULE,
125126
.obj_size = sizeof(struct vsock_sock),
127+
.close = vsock_close,
126128
#ifdef CONFIG_BPF_SYSCALL
127129
.psock_update_sk_prot = vsock_bpf_update_proto,
128130
#endif
@@ -797,39 +799,37 @@ static bool sock_type_connectible(u16 type)
797799

798800
static void __vsock_release(struct sock *sk, int level)
799801
{
800-
if (sk) {
801-
struct sock *pending;
802-
struct vsock_sock *vsk;
803-
804-
vsk = vsock_sk(sk);
805-
pending = NULL; /* Compiler warning. */
802+
struct vsock_sock *vsk;
803+
struct sock *pending;
806804

807-
/* When "level" is SINGLE_DEPTH_NESTING, use the nested
808-
* version to avoid the warning "possible recursive locking
809-
* detected". When "level" is 0, lock_sock_nested(sk, level)
810-
* is the same as lock_sock(sk).
811-
*/
812-
lock_sock_nested(sk, level);
805+
vsk = vsock_sk(sk);
806+
pending = NULL; /* Compiler warning. */
813807

814-
if (vsk->transport)
815-
vsk->transport->release(vsk);
816-
else if (sock_type_connectible(sk->sk_type))
817-
vsock_remove_sock(vsk);
808+
/* When "level" is SINGLE_DEPTH_NESTING, use the nested
809+
* version to avoid the warning "possible recursive locking
810+
* detected". When "level" is 0, lock_sock_nested(sk, level)
811+
* is the same as lock_sock(sk).
812+
*/
813+
lock_sock_nested(sk, level);
818814

819-
sock_orphan(sk);
820-
sk->sk_shutdown = SHUTDOWN_MASK;
815+
if (vsk->transport)
816+
vsk->transport->release(vsk);
817+
else if (sock_type_connectible(sk->sk_type))
818+
vsock_remove_sock(vsk);
821819

822-
skb_queue_purge(&sk->sk_receive_queue);
820+
sock_orphan(sk);
821+
sk->sk_shutdown = SHUTDOWN_MASK;
823822

824-
/* Clean up any sockets that never were accepted. */
825-
while ((pending = vsock_dequeue_accept(sk)) != NULL) {
826-
__vsock_release(pending, SINGLE_DEPTH_NESTING);
827-
sock_put(pending);
828-
}
823+
skb_queue_purge(&sk->sk_receive_queue);
829824

830-
release_sock(sk);
831-
sock_put(sk);
825+
/* Clean up any sockets that never were accepted. */
826+
while ((pending = vsock_dequeue_accept(sk)) != NULL) {
827+
__vsock_release(pending, SINGLE_DEPTH_NESTING);
828+
sock_put(pending);
832829
}
830+
831+
release_sock(sk);
832+
sock_put(sk);
833833
}
834834

835835
static void vsock_sk_destruct(struct sock *sk)
@@ -901,9 +901,22 @@ void vsock_data_ready(struct sock *sk)
901901
}
902902
EXPORT_SYMBOL_GPL(vsock_data_ready);
903903

904+
/* Dummy callback required by sockmap.
905+
* See unconditional call of saved_close() in sock_map_close().
906+
*/
907+
static void vsock_close(struct sock *sk, long timeout)
908+
{
909+
}
910+
904911
static int vsock_release(struct socket *sock)
905912
{
906-
__vsock_release(sock->sk, 0);
913+
struct sock *sk = sock->sk;
914+
915+
if (!sk)
916+
return 0;
917+
918+
sk->sk_prot->close(sk, 0);
919+
__vsock_release(sk, 0);
907920
sock->sk = NULL;
908921
sock->state = SS_FREE;
909922

0 commit comments

Comments
 (0)