mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 10:17:32 +00:00
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: 634f1a7110b4 ("vsock: support sockmap") Signed-off-by: Michal Luczaj <mhal@rbox.co> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Reviewed-by: Luigi Leonardi <leonardi@redhat.com> Link: https://lore.kernel.org/r/20241118-vsock-bpf-poll-close-v1-3-f1b9669cacdc@rbox.co Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: John Fastabend <john.fastabend@gmail.com>
This commit is contained in:
parent
9c2a2a4513
commit
135ffc7bec
@ -117,12 +117,14 @@
|
|||||||
static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr);
|
static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr);
|
||||||
static void vsock_sk_destruct(struct sock *sk);
|
static void vsock_sk_destruct(struct sock *sk);
|
||||||
static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
|
static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
|
||||||
|
static void vsock_close(struct sock *sk, long timeout);
|
||||||
|
|
||||||
/* Protocol family. */
|
/* Protocol family. */
|
||||||
struct proto vsock_proto = {
|
struct proto vsock_proto = {
|
||||||
.name = "AF_VSOCK",
|
.name = "AF_VSOCK",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.obj_size = sizeof(struct vsock_sock),
|
.obj_size = sizeof(struct vsock_sock),
|
||||||
|
.close = vsock_close,
|
||||||
#ifdef CONFIG_BPF_SYSCALL
|
#ifdef CONFIG_BPF_SYSCALL
|
||||||
.psock_update_sk_prot = vsock_bpf_update_proto,
|
.psock_update_sk_prot = vsock_bpf_update_proto,
|
||||||
#endif
|
#endif
|
||||||
@ -797,9 +799,8 @@ static bool sock_type_connectible(u16 type)
|
|||||||
|
|
||||||
static void __vsock_release(struct sock *sk, int level)
|
static void __vsock_release(struct sock *sk, int level)
|
||||||
{
|
{
|
||||||
if (sk) {
|
|
||||||
struct sock *pending;
|
|
||||||
struct vsock_sock *vsk;
|
struct vsock_sock *vsk;
|
||||||
|
struct sock *pending;
|
||||||
|
|
||||||
vsk = vsock_sk(sk);
|
vsk = vsock_sk(sk);
|
||||||
pending = NULL; /* Compiler warning. */
|
pending = NULL; /* Compiler warning. */
|
||||||
@ -830,7 +831,6 @@ static void __vsock_release(struct sock *sk, int level)
|
|||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void vsock_sk_destruct(struct sock *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);
|
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)
|
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->sk = NULL;
|
||||||
sock->state = SS_FREE;
|
sock->state = SS_FREE;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user