From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1792774125; b=gsYc8X30Ta1dA3J6w/D/ZGta1QuQF4hfBejMnS6p2mt6uNp374vFeweDKk0d+7+Uon19 14LGqiTaDvN6Y4UNvYsqlgmD1IkaFwWiWG9Mw/eOwJkgXxbKL3QgH6KKTmw01COdRWctY 6QKeo4oRPA5+EeIcQEU9mLQph33nTmFCBj2kA65/8fw5pl3dtyIvo2vLbFoKJwtSvguD2 b+XhkJN1U5PnbtU1tv4P1/+IdyZAW9KVht9zLYd9XohBYj9B6yej4dQefcD/OqllUJTu1 xrolpEH3J48wMnrT9VF6+wVI4ObWk7V+EWxdAyfABf4P1DJRzE9GL+HwpPDKt0DvaXA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792774125; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=93e1ppYfbVxIvLEYOZdFEOUxyZodGu1wCd2Jj/xmZss=; b=Wl9YVcyxqkGBuOpI5u9Ji4mdBxMvDUMspNe1VmpF4wfG7kqPcd6vTcdqTyCgWsb6Aw9j QdjsFuTqGD0wsxVcUQdOUoOGEcWX3nEQqeA0aYg/yR/6WQAopC4p1vTZG9l23UM9Erymx 3HGfEsGafpr02KmxALBZFHALA+fRQx2xc3OXcq/X98Oxxvp2Zpnpn07ifwE5tzNlmSooo LVtReCMfWyNPMxQjn8tqTyTE2BZ8SQPLv3/IkYzKasgANC1ShikgXEb0Hi5aVz+ArWXrR D7NtRU3YrbSI5QBspKWiiiAVmQheurMOpF3bhq0c+6Fjlma+zUyXd1WxlInLLt78RyA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=cRF8F4TG; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40476606A31E; Fri, 23 Oct 2026 16:48:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=cRF8F4TG Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3E24B1F01828; Fri, 23 Oct 2026 16:48:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1792774124; bh=93e1ppYfbVxIvLEYOZdFEOUxyZodGu1wCd2Jj/xmZss=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cRF8F4TGKaTcpcLct7OEUy9lJH3Qe1qYTvdEfA7ApVGnsO+LBVXQeBnC8xbDfCbss CrRJzoRWO+ZBX67+yIUkThFqV94NTptWTxNaJHFdHr6j1iH7hZLejHF4BBh0a4s/b4 ats6JABktqI49S8R9K18LdHp1xoT03ZF+9QcWZ+E= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Aswin Karuvally , Bryam Vargas , Alexandra Winter , Jakub Kicinski Subject: [PATCH 6.18 128/193] net/iucv: fix the recvmsg window update Date: Fri, 23 Oct 2026 18:36:45 +0200 Message-ID: <20261023163717.236101744@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261023163714.201276352@linuxfoundation.org> References: <20261023163714.201276352@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Bryam Vargas commit fa5acd038ea657ad5033713d6916214cbd349151 upstream. iucv_sock_recvmsg() sends the HiperSockets-only AF_IUCV_FLAG_WIN without testing the transport, so on a classic z/VM socket iucv_send_ctrl() sizes the skb through a NULL iucv->hs_dev. SO_MSGLIMIT accepts 1, so msglimit / 2 is zero and one recvmsg() on its own socket is enough for an unprivileged process to take a spurious disconnect. It also calls iucv_send_ctrl() under spin_lock_bh(&message_q.lock), which allocates GFP_KERNEL inside a section the code treats as atomic. Sending outside that lock lets two recvmsg() reach afiucv_hs_send() at once, where msg_recv is sampled for the advertised window and subtracted after dev_queue_xmit() -- and sendmsg reaches that counter under lock_sock() while recvmsg holds no socket lock, so both can subtract the same value, the counter goes negative and the credit reaches the peer twice. Test the transport, claim the credit with atomic_xchg() after the last error exit and hand it back if the transmit fails, and send once the lock is dropped. Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport") Fixes: 238965b71b96 ("net/af_iucv: build proper skbs for HiperTransport") Cc: stable@vger.kernel.org Tested-by: Aswin Karuvally Signed-off-by: Bryam Vargas Reviewed-by: Alexandra Winter Link: https://patch.msgid.link/20260828-b4-disp-33fac0ed-v3-1-e6d061880ee0@proton.me Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/iucv/af_iucv.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -208,12 +208,6 @@ static int afiucv_hs_send(struct iucv_me phs_hdr->flags = flags; if (flags == AF_IUCV_FLAG_SYN) phs_hdr->window = iucv->msglimit; - else if ((flags == AF_IUCV_FLAG_WIN) || !flags) { - confirm_recv = atomic_read(&iucv->msg_recv); - phs_hdr->window = confirm_recv; - if (confirm_recv) - phs_hdr->flags = phs_hdr->flags | AF_IUCV_FLAG_WIN; - } memcpy(phs_hdr->destUserID, iucv->dst_user_id, 8); memcpy(phs_hdr->destAppName, iucv->dst_name, 8); memcpy(phs_hdr->srcUserID, iucv->src_user_id, 8); @@ -248,13 +242,22 @@ static int afiucv_hs_send(struct iucv_me } skb->protocol = cpu_to_be16(ETH_P_AF_IUCV); + /* Claim the receive credit here, not while building the header: every + * way this frame can be dropped has now been ruled out, so the window + * is zeroed only for as long as the transmit itself takes. + */ + if (flags == AF_IUCV_FLAG_WIN || !flags) { + confirm_recv = atomic_xchg(&iucv->msg_recv, 0); + phs_hdr->window = confirm_recv; + if (confirm_recv) + phs_hdr->flags = phs_hdr->flags | AF_IUCV_FLAG_WIN; + } + atomic_inc(&iucv->skbs_in_xmit); err = dev_queue_xmit(skb); if (net_xmit_eval(err)) { atomic_dec(&iucv->skbs_in_xmit); - } else { - atomic_sub(confirm_recv, &iucv->msg_recv); - WARN_ON(atomic_read(&iucv->msg_recv) < 0); + atomic_add(confirm_recv, &iucv->msg_recv); } return net_xmit_eval(err); @@ -1238,6 +1241,7 @@ static int iucv_sock_recvmsg(struct sock struct iucv_sock *iucv = iucv_sk(sk); unsigned int copied, rlen; struct sk_buff *skb, *rskb, *cskb; + bool send_win = false; int err = 0; u32 offset; @@ -1328,16 +1332,20 @@ static int iucv_sock_recvmsg(struct sock 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) >= - iucv->msglimit / 2) { - err = iucv_send_ctrl(sk, AF_IUCV_FLAG_WIN); - if (err) { - sk->sk_state = IUCV_DISCONN; - sk->sk_state_change(sk); - } - } + if (iucv->transport == AF_IUCV_TRANS_HIPER && + atomic_read(&iucv->msg_recv) >= + iucv->msglimit / 2) + send_win = true; } spin_unlock_bh(&iucv->message_q.lock); + + if (send_win) { + err = iucv_send_ctrl(sk, AF_IUCV_FLAG_WIN); + if (err) { + sk->sk_state = IUCV_DISCONN; + sk->sk_state_change(sk); + } + } } done: