[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <mpv4ljrxyucr23x4hj7k7s4vmtvv3bgeq7uct3t44ghaw35l4r@wanp7mklhw7x>
Date: Tue, 21 Oct 2025 12:09:26 +0200
From: Stefano Garzarella <sgarzare@...hat.com>
To: syzbot <syzbot+10e35716f8e4929681fa@...kaller.appspotmail.com>
Cc: davem@...emloft.net, edumazet@...gle.com, horms@...nel.org,
kuba@...nel.org, linux-kernel@...r.kernel.org, netdev@...r.kernel.org,
pabeni@...hat.com, syzkaller-bugs@...glegroups.com, virtualization@...ts.linux.dev,
Michal Luczaj <mhal@...x.co>
Subject: Re: [syzbot] [virt?] [net?] possible deadlock in vsock_linger
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;
Powered by blists - more mailing lists