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

--- 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;


Reply via email to