Skip to content

Commit a130069

Browse files
edumazetkuba-moo
authored andcommitted
net: rose: lock the socket in rose_bind()
syzbot reported a soft lockup in rose_loopback_timer(), with a repro calling bind() from multiple threads. rose_bind() must lock the socket to avoid this issue. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+7ff41b5215f0c534534e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/67a0f78d.050a0220.d7c5a.00a0.GAE@google.com/T/#u Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Link: https://patch.msgid.link/20250203170838.3521361-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 028676b commit a130069

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

net/rose/af_rose.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -701,11 +701,9 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
701701
struct net_device *dev;
702702
ax25_address *source;
703703
ax25_uid_assoc *user;
704+
int err = -EINVAL;
704705
int n;
705706

706-
if (!sock_flag(sk, SOCK_ZAPPED))
707-
return -EINVAL;
708-
709707
if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose))
710708
return -EINVAL;
711709

@@ -718,8 +716,15 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
718716
if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS)
719717
return -EINVAL;
720718

721-
if ((dev = rose_dev_get(&addr->srose_addr)) == NULL)
722-
return -EADDRNOTAVAIL;
719+
lock_sock(sk);
720+
721+
if (!sock_flag(sk, SOCK_ZAPPED))
722+
goto out_release;
723+
724+
err = -EADDRNOTAVAIL;
725+
dev = rose_dev_get(&addr->srose_addr);
726+
if (!dev)
727+
goto out_release;
723728

724729
source = &addr->srose_call;
725730

@@ -730,7 +735,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
730735
} else {
731736
if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
732737
dev_put(dev);
733-
return -EACCES;
738+
err = -EACCES;
739+
goto out_release;
734740
}
735741
rose->source_call = *source;
736742
}
@@ -753,8 +759,10 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
753759
rose_insert_socket(sk);
754760

755761
sock_reset_flag(sk, SOCK_ZAPPED);
756-
757-
return 0;
762+
err = 0;
763+
out_release:
764+
release_sock(sk);
765+
return err;
758766
}
759767

760768
static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)

0 commit comments

Comments
 (0)