Skip to content

Commit dd056f7

Browse files
committed
vsock: Fix transport_* TOCTOU
jira VULN-80680 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: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 222ef4f commit dd056f7

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
@@ -393,6 +393,8 @@ EXPORT_SYMBOL_GPL(vsock_enqueue_accept);
393393

394394
static bool vsock_use_local_transport(unsigned int remote_cid)
395395
{
396+
lockdep_assert_held(&vsock_register_mutex);
397+
396398
if (!transport_local)
397399
return false;
398400

@@ -450,6 +452,8 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
450452

451453
remote_flags = vsk->remote_addr.svm_flags;
452454

455+
mutex_lock(&vsock_register_mutex);
456+
453457
switch (sk->sk_type) {
454458
case SOCK_DGRAM:
455459
new_transport = transport_dgram;
@@ -464,12 +468,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
464468
new_transport = transport_h2g;
465469
break;
466470
default:
467-
return -ESOCKTNOSUPPORT;
471+
ret = -ESOCKTNOSUPPORT;
472+
goto err;
468473
}
469474

470475
if (vsk->transport) {
471-
if (vsk->transport == new_transport)
472-
return 0;
476+
if (vsk->transport == new_transport) {
477+
ret = 0;
478+
goto err;
479+
}
473480

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

499514
ret = new_transport->init(vsk, psk);
500515
if (ret) {
@@ -505,6 +520,9 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
505520
vsk->transport = new_transport;
506521

507522
return 0;
523+
err:
524+
mutex_unlock(&vsock_register_mutex);
525+
return ret;
508526
}
509527
EXPORT_SYMBOL_GPL(vsock_assign_transport);
510528

0 commit comments

Comments
 (0)