Morduan Zang
unread,Apr 22, 2026, 2:35:35 AM (yesterday) Apr 22Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Remi Denis-Courmont, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, net...@vger.kernel.org, linux-...@vger.kernel.org, syzkall...@googlegroups.com, syzbot+706f5e...@syzkaller.appspotmail.com, Morduan Zang, zhanjun
syzbot reported a kernel BUG triggered from pn_socket_sendmsg() via
pn_socket_autobind():
kernel BUG at net/phonet/socket.c:213!
RIP: 0010:pn_socket_autobind net/phonet/socket.c:213 [inline]
RIP: 0010:pn_socket_sendmsg+0x240/0x250 net/phonet/socket.c:421
Call Trace:
sock_sendmsg_nosec+0x112/0x150 net/socket.c:797
__sock_sendmsg net/socket.c:812 [inline]
__sys_sendto+0x402/0x590 net/socket.c:2280
...
pn_socket_autobind() calls pn_socket_bind() with port 0 and, on
-EINVAL, assumes the socket was already bound and asserts that the
port is non-zero:
err = pn_socket_bind(sock, ..., sizeof(struct sockaddr_pn));
if (err != -EINVAL)
return err;
BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
return 0; /* socket was already bound */
However pn_socket_bind() also returns -EINVAL when sk->sk_state is not
TCP_CLOSE, even when the socket has never been bound and pn_port() is
still 0. In that case the BUG_ON() fires and panics the kernel from a
user-triggerable path.
Treat the "bind returned -EINVAL but pn_port() is still 0" case as a
regular error and propagate -EINVAL to the caller instead of crashing.
Existing callers already translate a non-zero return from
pn_socket_autobind() into -ENOBUFS/-EAGAIN, so returning -EINVAL here
only changes behaviour from panic to a normal errno.
Fixes: ba113a94b750 ("Phonet: common socket glue")
Reported-by:
syzbot+706f5e...@syzkaller.appspotmail.com
Closes:
https://syzkaller.appspot.com/bug?extid=706f5eb79044e686c794
Signed-off-by: Morduan Zang <
zhang...@uniontech.com>
Signed-off-by: zhanjun <
zha...@uniontech.com>
---
net/phonet/socket.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 4423d483c630..de9108adfe1c 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -210,7 +210,15 @@ static int pn_socket_autobind(struct socket *sock)
sizeof(struct sockaddr_pn));
if (err != -EINVAL)
return err;
- BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
+ /*
+ * pn_socket_bind() can return -EINVAL both when the socket is
+ * already bound (pn_port() != 0) and when sk_state != TCP_CLOSE
+ * without a prior bind. Only the former is an "already bound"
+ * success for autobind; otherwise propagate -EINVAL instead of
+ * crashing the kernel.
+ */
+ if (!pn_port(pn_sk(sock->sk)->sobject))
+ return -EINVAL;
return 0; /* socket was already bound */
}
--
2.50.1