Commit 135ffc7b authored by Michal Luczaj's avatar Michal Luczaj Committed by Alexei Starovoitov
Browse files

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: 634f1a71 ("vsock: support sockmap")
Signed-off-by: default avatarMichal Luczaj <mhal@rbox.co>
Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Reviewed-by: default avatarLuigi Leonardi <leonardi@redhat.com>
Link: https://lore.kernel.org/r/20241118-vsock-bpf-poll-close-v1-3-f1b9669cacdc@rbox.co


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
parent 9c2a2a45
Loading
Loading
Loading
Loading
+40 −27
Original line number Diff line number Diff line
@@ -117,12 +117,14 @@
static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr);
static void vsock_sk_destruct(struct sock *sk);
static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
static void vsock_close(struct sock *sk, long timeout);

/* Protocol family. */
struct proto vsock_proto = {
	.name = "AF_VSOCK",
	.owner = THIS_MODULE,
	.obj_size = sizeof(struct vsock_sock),
	.close = vsock_close,
#ifdef CONFIG_BPF_SYSCALL
	.psock_update_sk_prot = vsock_bpf_update_proto,
#endif
@@ -797,9 +799,8 @@ static bool sock_type_connectible(u16 type)

static void __vsock_release(struct sock *sk, int level)
{
	if (sk) {
		struct sock *pending;
	struct vsock_sock *vsk;
	struct sock *pending;

	vsk = vsock_sk(sk);
	pending = NULL;	/* Compiler warning. */
@@ -830,7 +831,6 @@ static void __vsock_release(struct sock *sk, int level)
	release_sock(sk);
	sock_put(sk);
}
}

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

/* Dummy callback required by sockmap.
 * See unconditional call of saved_close() in sock_map_close().
 */
static void vsock_close(struct sock *sk, long timeout)
{
}

static int vsock_release(struct socket *sock)
{
	__vsock_release(sock->sk, 0);
	struct sock *sk = sock->sk;

	if (!sk)
		return 0;

	sk->sk_prot->close(sk, 0);
	__vsock_release(sk, 0);
	sock->sk = NULL;
	sock->state = SS_FREE;