summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/phonet/socket.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index c4af26357144..631a99cdbd00 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -208,9 +208,15 @@ static int pn_socket_autobind(struct socket *sock)
sa.spn_family = AF_PHONET;
err = pn_socket_bind(sock, (struct sockaddr_unsized *)&sa,
sizeof(struct sockaddr_pn));
- if (err != -EINVAL)
+ /*
+ * pn_socket_bind() also returns -EINVAL when sk_state != TCP_CLOSE
+ * without a prior bind, so -EINVAL alone is not sufficient to infer
+ * that the socket was already bound. Only treat it as "already
+ * bound" when the port is non-zero; otherwise propagate the error
+ * instead of crashing the kernel.
+ */
+ if (err != -EINVAL || unlikely(!pn_port(pn_sk(sock->sk)->sobject)))
return err;
- BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
return 0; /* socket was already bound */
}