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: 5+ 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 via B4 Relay
2026-08-15 16:04 ` [PATCH net 1/2] net/iucv: only send the window update on HiperSockets sockets Bryam Vargas via B4 Relay
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 via B4 Relay
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox