[PATCH net] net/iucv: reconcile the socket state when connect() severs the path

Bryam Vargas via B4 Relay <[email protected]>
Newsgroups org.kernel.vger.linux-s390,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
From: Bryam Vargas <[email protected]>

A connack can land between iucv_sock_wait() returning an error and the
sever at the end of iucv_sock_connect(): iucv_callback_connack() writes
IUCV_CONNECTED from the iucv tasklet with no socket lock, and lock_sock()
does not exclude it. The sever clears iucv->path and leaves the state, so
connect() fails on a socket still claiming a connection it no longer has,
and a later sendmsg() reaches iucv->path->msglim through the NULL pointer
inside iucv_below_msglim(). The sever runs on every failed classic
connect, O_NONBLOCK included.

Reconcile only that case, so an ordinary failed connect still returns the
socket to its pre-connect state. The sever is a barrier against a later
connack: iucv_path_sever() clears the path from iucv_path_table[] under
the lock the tasklet holds across dispatch.

Fixes: 18becbc5479f ("af_iucv: avoid left over IUCV connections from failing connects")
Cc: [email protected]
Signed-off-by: Bryam Vargas <[email protected]>
---
 net/iucv/af_iucv.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index ea047bab65e7..6fb0041c4c98 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -778,8 +778,16 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr_unsized *addr,
 	if (sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_CLOSED)
 		err = -ECONNREFUSED;
 
-	if (err && iucv->transport == AF_IUCV_TRANS_IUCV)
+	if (err && iucv->transport == AF_IUCV_TRANS_IUCV) {
 		iucv_sever_path(sk, 0);
+		/* A connack may have landed while the wait was unwinding; the
+		 * path is gone, so the socket must not still claim it.
+		 */
+		if (sk->sk_state == IUCV_CONNECTED) {
+			sk->sk_state = IUCV_DISCONN;
+			sk->sk_state_change(sk);
+		}
+	}
 
 done:
 	release_sock(sk);

---
base-commit: a59f57e2aa127c5354168d2ec4bac920df1be4f4
change-id: 20260815-b4-disp-e1faf4b7-feddd1575cc2

Best regards,
--  
Bryam Vargas <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.