Skip to content

Commit e13064d

Browse files
vsock: Fix transport_* TOCTOU
jira VULN-80685 cve CVE-2025-38461 commit-author Michal Luczaj <mhal@rbox.co> commit 687aa0c Transport assignment may race with module unload. Protect new_transport from becoming a stale pointer. This also takes care of an insecure call in vsock_use_local_transport(); add a lockdep assert. BUG: unable to handle page fault for address: fffffbfff8056000 Oops: Oops: 0000 [#1] SMP KASAN RIP: 0010:vsock_assign_transport+0x366/0x600 Call Trace: vsock_connect+0x59c/0xc40 __sys_connect+0xe8/0x100 __x64_sys_connect+0x6e/0xc0 do_syscall_64+0x92/0x1c0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 Fixes: c0cfa2d ("vsock: add multi-transports support") Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Michal Luczaj <mhal@rbox.co> Link: https://patch.msgid.link/20250703-vsock-transports-toctou-v4-2-98f0eb530747@rbox.co Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 687aa0c) Signed-off-by: Shreeya Patel <spatel@ciq.com>
1 parent 1e09b1d commit e13064d

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

net/vmw_vsock/af_vsock.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ EXPORT_SYMBOL_GPL(vsock_enqueue_accept);
404404

405405
static bool vsock_use_local_transport(unsigned int remote_cid)
406406
{
407+
lockdep_assert_held(&vsock_register_mutex);
408+
407409
if (!transport_local)
408410
return false;
409411

@@ -461,6 +463,8 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
461463

462464
remote_flags = vsk->remote_addr.svm_flags;
463465

466+
mutex_lock(&vsock_register_mutex);
467+
464468
switch (sk->sk_type) {
465469
case SOCK_DGRAM:
466470
new_transport = transport_dgram;
@@ -476,12 +480,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
476480
new_transport = transport_h2g;
477481
break;
478482
default:
479-
return -ESOCKTNOSUPPORT;
483+
ret = -ESOCKTNOSUPPORT;
484+
goto err;
480485
}
481486

482487
if (vsk->transport) {
483-
if (vsk->transport == new_transport)
484-
return 0;
488+
if (vsk->transport == new_transport) {
489+
ret = 0;
490+
goto err;
491+
}
485492

486493
/* transport->release() must be called with sock lock acquired.
487494
* This path can only be taken during vsock_connect(), where we
@@ -496,8 +503,16 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
496503
/* We increase the module refcnt to prevent the transport unloading
497504
* while there are open sockets assigned to it.
498505
*/
499-
if (!new_transport || !try_module_get(new_transport->module))
500-
return -ENODEV;
506+
if (!new_transport || !try_module_get(new_transport->module)) {
507+
ret = -ENODEV;
508+
goto err;
509+
}
510+
511+
/* It's safe to release the mutex after a successful try_module_get().
512+
* Whichever transport `new_transport` points at, it won't go away until
513+
* the last module_put() below or in vsock_deassign_transport().
514+
*/
515+
mutex_unlock(&vsock_register_mutex);
501516

502517
if (sk->sk_type == SOCK_SEQPACKET) {
503518
if (!new_transport->seqpacket_allow ||
@@ -516,6 +531,9 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
516531
vsk->transport = new_transport;
517532

518533
return 0;
534+
err:
535+
mutex_unlock(&vsock_register_mutex);
536+
return ret;
519537
}
520538
EXPORT_SYMBOL_GPL(vsock_assign_transport);
521539

0 commit comments

Comments
 (0)