From: Jakub Kicinski <kuba@kernel.org>
To: hexlabsecurity@proton.me
Cc: Jakub Kicinski <kuba@kernel.org>,
pabeni@redhat.com, twinkler@linux.ibm.com, wintera@linux.ibm.com,
davem@davemloft.net, edumazet@google.com, netdev@vger.kernel.org,
ursula.braun@de.ibm.com, linux-s390@vger.kernel.org,
hidayath@linux.ibm.com, horms@kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH net 1/2] net/iucv: only send the window update on HiperSockets sockets
Date: Thu, 20 Aug 2026 13:33:30 -0700 [thread overview]
Message-ID: <20260820203330.1134874-1-kuba@kernel.org> (raw)
In-Reply-To: <20260815-b4-disp-8a791503-v1-1-fbae9a511144@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: only send the window update on HiperSockets sockets
This adds a transport test before iucv_sock_recvmsg() sends
AF_IUCV_FLAG_WIN, so that iucv_send_ctrl() is no longer called on classic
z/VM sockets where iucv->hs_dev is NULL. Two questions below, one about
the impact statement in the changelog and one about the surrounding
msg_recv accounting.
> iucv_sock_recvmsg() sends AF_IUCV_FLAG_WIN without testing the transport,
> but that flag exists only on HiperSockets. On a classic z/VM socket
> iucv->hs_dev is NULL and iucv_send_ctrl() sizes the skb from
> LL_RESERVED_SPACE(iucv->hs_dev), so the read goes through NULL;
> afiucv_hs_send() then returns -ENODEV and recvmsg() moves the socket to
> IUCV_DISCONN. Reaching it takes an application that sets SO_MSGLIMIT to 1
> on its own socket, since msg_recv is incremented only on the HiperSockets
> path, so this is a correctness fix rather than a security one.
[Severity: Medium]
The bug being fixed here is pre-existing (3881ac441f64) and is not
introduced by this patch, but is the concluding sentence, "so this is a
correctness fix rather than a security one", accurate for a patch carrying
Cc: stable?
The trigger is entirely under the control of an unprivileged local process
using the ordinary socket API. SO_MSGLIMIT accepts 1 in iucv_setsockopt():
if (val < 1 || val > U16_MAX)
rc = -EINVAL;
else
iucv->msglimit = val;
msg_recv stays at 0 on a classic socket, so msglimit / 2 == 0 makes the
old predicate 0 >= 0 on every successful non-PEEK recvmsg(), and
iucv_send_ctrl() then evaluates:
net/iucv/af_iucv.c:iucv_send_ctrl() {
blen = sizeof(struct af_iucv_trans_hdr) +
LL_RESERVED_SPACE(iucv->hs_dev);
with hs_dev == NULL, before afiucv_hs_send() gets a chance to return
-ENODEV on its !skb->dev test.
The changelog itself then says "with lowcore relocation it faults", and
relocate_lowcore is a supported s390 boot parameter. On such kernels an
ordinary recvmsg() from an unprivileged process oopses, which reads like a
local denial of service rather than a correctness issue. Would it be worth
restating the impact so stable maintainers can prioritise and tag it
accordingly?
> diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
> index ea047bab65e7c..0bc4a15f4b565 100644
> --- a/net/iucv/af_iucv.c
> +++ b/net/iucv/af_iucv.c
> @@ -1331,7 +1331,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,
> if (skb_queue_empty(&iucv->backlog_skb_q)) {
> if (!list_empty(&iucv->message_q.list))
> iucv_process_message_q(sk);
> - if (atomic_read(&iucv->msg_recv) >=
> + if (iucv->transport == AF_IUCV_TRANS_HIPER &&
> + atomic_read(&iucv->msg_recv) >=
> iucv->msglimit / 2) {
> err = iucv_send_ctrl(sk, AF_IUCV_FLAG_WIN);
> if (err) {
[Severity: High]
This is a pre-existing issue and is not introduced by this patch, but since
the patch touches this exact accounting block, can the WARN a few lines
above be reached from remote input on the HiperSockets path?
Just before the hunk, iucv_sock_recvmsg() does:
consume_skb(skb);
if (iucv->transport == AF_IUCV_TRANS_HIPER) {
atomic_inc(&iucv->msg_recv);
if (atomic_read(&iucv->msg_recv) > iucv->msglimit) {
WARN_ON(1);
iucv_sock_close(sk);
return -EFAULT;
}
}
The only place msg_recv is decremented is afiucv_hs_send() with
atomic_sub(confirm_recv, &iucv->msg_recv), reached through the
iucv_send_ctrl(sk, AF_IUCV_FLAG_WIN) call in this hunk, and that call sits
under:
if (skb_queue_empty(&iucv->backlog_skb_q)) {
Meanwhile afiucv_hs_callback_rx() queues every accepted frame without
enforcing the window it advertised to the peer:
net/iucv/af_iucv.c:afiucv_hs_callback_rx() {
spin_lock(&iucv->message_q.lock);
if (skb_queue_empty(&iucv->backlog_skb_q)) {
if (__sock_queue_rcv_skb(sk, skb))
skb_queue_tail(&iucv->backlog_skb_q, skb);
} else
skb_queue_tail(&iucv_sk(sk)->backlog_skb_q, skb);
So if a non-conforming peer floods the socket, the receive queue hits
sk_rcvbuf, __sock_queue_rcv_skb() keeps failing in the drain loop above,
the skb is re-queued at the head of backlog_skb_q and the loop breaks.
backlog_skb_q then stays non-empty, no window update is sent, and msg_recv
keeps incrementing on each recvmsg() until it passes msglimit
(IUCV_HIPER_MSGLIM_DEFAULT is 128) and the WARN fires. With panic_on_warn
that would be a panic driven by a remote peer.
The same WARN also looks reachable locally with SO_MSGLIMIT set to 1 and
two concurrent recvmsg() threads, since recvmsg() does not hold the socket
lock across the atomic_inc.
Would a rate-limited message plus a drop or reset be a better response to a
peer protocol violation here than WARN_ON(1)?
--
pw-bot: cr
next prev parent reply other threads:[~2026-08-20 20:33 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-15 16:04 [PATCH net 0/2] net/iucv: fix the recvmsg window update Bryam Vargas
2026-08-15 16:04 ` Bryam Vargas via B4 Relay
2026-08-15 16:04 ` [PATCH net 1/2] net/iucv: only send the window update on HiperSockets sockets Bryam Vargas
2026-08-15 16:04 ` Bryam Vargas via B4 Relay
2026-08-16 16:04 ` sashiko-bot
2026-08-20 20:33 ` Jakub Kicinski [this message]
2026-08-15 16:04 ` [PATCH net 2/2] net/iucv: send the window update outside message_q.lock Bryam Vargas
2026-08-15 16:04 ` Bryam Vargas via B4 Relay
2026-08-16 16:04 ` sashiko-bot
2026-08-20 20:33 ` Jakub Kicinski
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=20260820203330.1134874-1-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.