All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: hexlabsecurity@proton.me
Cc: Jakub Kicinski <kuba@kernel.org>,
	edumazet@google.com, pabeni@redhat.com, davem@davemloft.net,
	wintera@linux.ibm.com, twinkler@linux.ibm.com,
	hidayath@linux.ibm.com, horms@kernel.org,
	linux-kernel@vger.kernel.org, ursula.braun@de.ibm.com,
	netdev@vger.kernel.org, linux-s390@vger.kernel.org
Subject: Re: [PATCH net] net/iucv: reconcile the socket state when connect() severs the path
Date: Thu, 20 Aug 2026 12:37:53 -0700	[thread overview]
Message-ID: <20260820193752.1074271-2-kuba@kernel.org> (raw)
In-Reply-To: <20260815-b4-disp-e1faf4b7-v1-1-2a8a143a0055@proton.me>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net/iucv: reconcile the socket state when connect() severs the path

When a classic AF_IUCV connect() fails and severs the path, the socket
could be left in IUCV_CONNECTED with iucv->path already NULL. The patch
adds a state reconciliation to IUCV_DISCONN right after iucv_sever_path()
so that a later sendmsg() does not walk the NULL path pointer.

> diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
> index ea047bab65e7c..6fb0041c4c987 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);
> +		}
> +	}

[Severity: Critical]
This isn't a bug introduced by this patch, but it should probably be
fixed at the same time. Does the same CONNECTED-with-NULL-path state
remain reachable from the HiperSockets receive path, so that the NULL
dereference described in the changelog survives?

afiucv_hs_rcv() matches sockets on the global iucv_sk_list by name only:

net/iucv/af_iucv.c:afiucv_hs_rcv() {
	...
	sk_for_each(sk, &iucv_sk_list.head) {
		if (trans_hdr->flags == AF_IUCV_FLAG_SYN) {
			...
		} else {
			if ((!memcmp(&iucv_sk(sk)->src_name,
				     trans_hdr->destAppName, 8)) &&
			    ...
			    (!memcmp(&iucv_sk(sk)->dst_user_id,
				     trans_hdr->srcUserID, 8))) {
				iucv = iucv_sk(sk);
				break;
	...
}

There is no check of iucv->transport, no check of iucv->hs_dev and no
network namespace check, and iucv_packet_type is registered globally in
afiucv_init() with dev_add_pack(&iucv_packet_type) and no .dev filter.

afiucv_hs_callback_synack() then only requires IUCV_BOUND before writing
the connected state:

net/iucv/af_iucv.c:afiucv_hs_callback_synack() {
	if (!iucv || sk->sk_state != IUCV_BOUND) {
		kfree_skb(skb);
		return NET_RX_SUCCESS;
	}

	bh_lock_sock(sk);
	iucv->msglimit_peer = iucv_trans_hdr(skb)->window;
	sk->sk_state = IUCV_CONNECTED;
	sk->sk_state_change(sk);
	...
}

So a classic-transport socket that has only been bound, or one whose
connect() failed with the wait timing out or being interrupted (path
severed to NULL, state left at IUCV_BOUND, which the new code does not
reconcile), can end up at IUCV_CONNECTED with iucv->path == NULL.

Once that happens, iucv_below_msglim() dereferences the NULL path:

net/iucv/af_iucv.c:iucv_below_msglim() {
	if (sk->sk_state != IUCV_CONNECTED)
		return 1;
	if (iucv->transport == AF_IUCV_TRANS_IUCV)
		return (atomic_read(&iucv->skbs_in_xmit) < iucv->path->msglim);
	...
}

and it is called from iucv_sock_poll():

	if (sock_writeable(sk) && iucv_below_msglim(sk))

which the sk_state_change() above has just woken, as well as from
iucv_sock_sendmsg() via iucv_sock_wait(sk, iucv_below_msglim(sk), timeo).
iucv_sock_sendmsg() also reads iucv->path->flags:

	if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags) &&

and passes iucv->path to pr_iucv->message_send().

The changelog says:

    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.

Is that statement complete? It holds for the classic iucv tasklet, where
iucv_tasklet_fn() holds iucv_table_lock across dispatch, but the
HiperSockets callbacks run from the netdev RX softirq under
bh_lock_sock() only, and are not excluded by iucv_table_lock.

Would it make sense to also check iucv->transport (and iucv->hs_dev)
in the afiucv_hs_rcv() socket lookup or in afiucv_hs_callback_synack(),
and/or to have iucv_below_msglim() and iucv_sock_sendmsg() test
iucv->path before dereferencing it?
-- 
pw-bot: cr

      parent reply	other threads:[~2026-08-20 19:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-15 15:43 [PATCH net] net/iucv: reconcile the socket state when connect() severs the path Bryam Vargas via B4 Relay
2026-08-15 15:43 ` Bryam Vargas
2026-08-16 15:43 ` sashiko-bot
2026-08-20 19:37 ` Jakub Kicinski [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260820193752.1074271-2-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hexlabsecurity@proton.me \
    --cc=hidayath@linux.ibm.com \
    --cc=horms@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=twinkler@linux.ibm.com \
    --cc=ursula.braun@de.ibm.com \
    --cc=wintera@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.