Skip to content

Commit c4b452c

Browse files
committed
Merge: bpf, vsock: Invoke proto::close on close()
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6745 JIRA: https://issues.redhat.com/browse/RHEL-81484 CVE: CVE-2025-21756 Upstream: Merged bpf, vsock: Invoke proto::close on close() vsock: Keep the binding until socket destruction https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6745 Fixes: c0cfa2d ("vsock: add multi-transports support") Fixes: 634f1a7 ("vsock: support sockmap") Fixes: fcdd224 ("vsock: Keep the binding until socket destruction") Signed-off-by: Jon Maloy <jmaloy@redhat.com> Approved-by: Stefano Garzarella <sgarzare@redhat.com> Approved-by: Luigi Leonardi <leonardi@redhat.com> Approved-by: Jay Shin <jaeshin@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents e4bb9a4 + 50568d9 commit c4b452c

File tree

1 file changed

+50
-27
lines changed

1 file changed

+50
-27
lines changed

net/vmw_vsock/af_vsock.c

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

120121
/* Protocol family. */
121122
struct proto vsock_proto = {
122123
.name = "AF_VSOCK",
123124
.owner = THIS_MODULE,
124125
.obj_size = sizeof(struct vsock_sock),
126+
.close = vsock_close,
125127
#ifdef CONFIG_BPF_SYSCALL
126128
.psock_update_sk_prot = vsock_bpf_update_proto,
127129
#endif
@@ -334,7 +336,10 @@ EXPORT_SYMBOL_GPL(vsock_find_connected_socket);
334336

335337
void vsock_remove_sock(struct vsock_sock *vsk)
336338
{
337-
vsock_remove_bound(vsk);
339+
/* Transport reassignment must not remove the binding. */
340+
if (sock_flag(sk_vsock(vsk), SOCK_DEAD))
341+
vsock_remove_bound(vsk);
342+
338343
vsock_remove_connected(vsk);
339344
}
340345
EXPORT_SYMBOL_GPL(vsock_remove_sock);
@@ -797,39 +802,44 @@ static bool sock_type_connectible(u16 type)
797802

798803
static void __vsock_release(struct sock *sk, int level)
799804
{
800-
if (sk) {
801-
struct sock *pending;
802-
struct vsock_sock *vsk;
805+
struct vsock_sock *vsk;
806+
struct sock *pending;
803807

804-
vsk = vsock_sk(sk);
805-
pending = NULL; /* Compiler warning. */
808+
vsk = vsock_sk(sk);
809+
pending = NULL; /* Compiler warning. */
806810

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);
811+
/* When "level" is SINGLE_DEPTH_NESTING, use the nested
812+
* version to avoid the warning "possible recursive locking
813+
* detected". When "level" is 0, lock_sock_nested(sk, level)
814+
* is the same as lock_sock(sk).
815+
*/
816+
lock_sock_nested(sk, level);
813817

814-
if (vsk->transport)
815-
vsk->transport->release(vsk);
816-
else if (sock_type_connectible(sk->sk_type))
817-
vsock_remove_sock(vsk);
818+
/* Indicate to vsock_remove_sock() that the socket is being released and
819+
* can be removed from the bound_table. Unlike transport reassignment
820+
* case, where the socket must remain bound despite vsock_remove_sock()
821+
* being called from the transport release() callback.
822+
*/
823+
sock_set_flag(sk, SOCK_DEAD);
818824

819-
sock_orphan(sk);
820-
sk->sk_shutdown = SHUTDOWN_MASK;
825+
if (vsk->transport)
826+
vsk->transport->release(vsk);
827+
else if (sock_type_connectible(sk->sk_type))
828+
vsock_remove_sock(vsk);
821829

822-
skb_queue_purge(&sk->sk_receive_queue);
830+
sock_orphan(sk);
831+
sk->sk_shutdown = SHUTDOWN_MASK;
823832

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-
}
833+
skb_queue_purge(&sk->sk_receive_queue);
829834

830-
release_sock(sk);
831-
sock_put(sk);
835+
/* Clean up any sockets that never were accepted. */
836+
while ((pending = vsock_dequeue_accept(sk)) != NULL) {
837+
__vsock_release(pending, SINGLE_DEPTH_NESTING);
838+
sock_put(pending);
832839
}
840+
841+
release_sock(sk);
842+
sock_put(sk);
833843
}
834844

835845
static void vsock_sk_destruct(struct sock *sk)
@@ -910,9 +920,22 @@ void vsock_data_ready(struct sock *sk)
910920
}
911921
EXPORT_SYMBOL_GPL(vsock_data_ready);
912922

923+
/* Dummy callback required by sockmap.
924+
* See unconditional call of saved_close() in sock_map_close().
925+
*/
926+
static void vsock_close(struct sock *sk, long timeout)
927+
{
928+
}
929+
913930
static int vsock_release(struct socket *sock)
914931
{
915-
__vsock_release(sock->sk, 0);
932+
struct sock *sk = sock->sk;
933+
934+
if (!sk)
935+
return 0;
936+
937+
sk->sk_prot->close(sk, 0);
938+
__vsock_release(sk, 0);
916939
sock->sk = NULL;
917940
sock->state = SS_FREE;
918941

0 commit comments

Comments
 (0)