On Mon, Oct 20, 2025 at 05:02:56PM -0700, syzbot wrote:
Hello,
syzbot found the following issue on:
HEAD commit: d9043c79ba68 Merge tag 'sched_urgent_for_v6.18_rc2' of git..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=130983cd980000
kernel config: https://syzkaller.appspot.com/x/.config?x=f3e7b5a3627a90dd
dashboard link: https://syzkaller.appspot.com/bug?extid=10e35716f8e4929681fa
compiler: gcc (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for
Debian) 2.40
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=17f0f52f980000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=11ea9734580000
#syz test
>From c32c21ea301aadc56160a57ddcd99f836a49f028 Mon Sep 17 00:00:00 2001
From: Stefano Garzarella <[email protected]>
Date: Tue, 21 Oct 2025 12:12:24 +0200
Subject: [PATCH] TODO
From: Stefano Garzarella <[email protected]>
---
net/vmw_vsock/af_vsock.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 4c2db6cca557..5434fe6a1d6b 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -565,6 +565,11 @@ static u32 vsock_registered_transport_cid(const struct
vsock_transport **transpo
return cid;
}
+/* vsock_find_cid() must be called outside lock_sock/release_sock
+ * section to avoid a potential lock inversion deadlock with
+ * vsock_assign_transport() where `vsock_register_mutex` is taken when
+ * `sk_lock-AF_VSOCK` is already held.
+ */
bool vsock_find_cid(unsigned int cid)
{
if (cid == vsock_registered_transport_cid(&transport_g2h))
@@ -735,23 +740,14 @@ static int __vsock_bind_dgram(struct vsock_sock *vsk,
return vsk->transport->dgram_bind(vsk, addr);
}
+/* The caller must ensure the socket is not already bound and provide a valid
+ * `addr` to bind (VMADDR_CID_ANY, or a CID assgined to a transport).
+ */
static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr)
{
struct vsock_sock *vsk = vsock_sk(sk);
int retval;
- /* First ensure this socket isn't already bound. */
- if (vsock_addr_bound(&vsk->local_addr))
- return -EINVAL;
-
- /* Now bind to the provided address or select appropriate values if
- * none are provided (VMADDR_CID_ANY and VMADDR_PORT_ANY). Note that
- * like AF_INET prevents binding to a non-local IP address (in most
- * cases), we only allow binding to a local CID.
- */
- if (addr->svm_cid != VMADDR_CID_ANY && !vsock_find_cid(addr->svm_cid))
- return -EADDRNOTAVAIL;
-
switch (sk->sk_socket->type) {
case SOCK_STREAM:
case SOCK_SEQPACKET:
@@ -991,15 +987,33 @@ vsock_bind(struct socket *sock, struct sockaddr *addr,
int addr_len)
{
int err;
struct sock *sk;
+ struct vsock_sock *vsk;
struct sockaddr_vm *vm_addr;
sk = sock->sk;
+ vsk = vsock_sk(sk);
if (vsock_addr_cast(addr, addr_len, &vm_addr) != 0)
return -EINVAL;
+ /* Like AF_INET prevents binding to a non-local IP address (in most
+ * cases), we only allow binding to a local CID.
+ */
+ if (vm_addr->svm_cid != VMADDR_CID_ANY &&
+ !vsock_find_cid(vm_addr->svm_cid))
+ return -EADDRNOTAVAIL;
+
lock_sock(sk);
+
+ /* Ensure this socket isn't already bound. */
+ if (vsock_addr_bound(&vsk->local_addr)) {
+ err = -EINVAL;
+ goto out;
+ }
+
err = __vsock_bind(sk, vm_addr);
+
+out:
release_sock(sk);
return err;
--
2.51.0