From nobody Thu Nov 27 14:00:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E719329BD96; Tue, 4 Nov 2025 12:15:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762258549; cv=none; b=YJvGr7/pVXNQRxnDke3oZYnd5oeqoCFy5KXUyEy5zUqwdAsdUkL1rSNfB4fcRiOaQTnHAFAU/wxQGqIP1D1YeYaEjzXOSwvqb7tUJ50B43uu999ti3GqAa+KAMod+Wg/dKLV3iFCCQ3nAf33DTbmaXQxF1lO/y4UCYfN7P4Oc3s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762258549; c=relaxed/simple; bh=ACw2vBX42jxFsM07eDSGgWZY/ej/53OwAi0/iqaL8aU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mwSFcPws9kyKNVpMPYnoN9t7X7Ho+OcJreVQ4Js+M28Qxd1QmFoXoBSdck+kOU7ki3nXhJz0SP9RZtP6XDuj6B/KOacnPg315JuqsQ2SYeu+CX9eymdJ8bfg55HDJJeciZ8vtboYepNcPdf5a6blL17O7qpg8t9XirCo1pucd4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sHPJU8ri; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sHPJU8ri" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C4312C16AAE; Tue, 4 Nov 2025 12:15:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762258548; bh=ACw2vBX42jxFsM07eDSGgWZY/ej/53OwAi0/iqaL8aU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sHPJU8ri2tjuWPp2vGJxJ3q3dyjji0vNPiacsibrWwBppMlC42uxZHzVGXD8iKES1 dtplSUQF01FOHHvBx8WkxuGfTQq3Ry6YJTeKQBrWwfQdx8inv90cbiYBiNJ8PIacZi 5qfxtd0bW5YijrRJkSlPpBEHtavnuWceDUWvRccAY/q77xBSCtffqN8wG7UydaZgiG plfAwS6YCUQDYMV0WJu5Ck/JLqLADdehtM/jN7SLJyCNvrhQPeRVDbyNfCDQdkKiP5 GeZFCHutf2bxSGN1pErfhepWeYdCS+vNDp0lFCaNyM+BswqzeL8HmjhVg8whHBThIL oRlGDsPT1Gkxw== From: "Matthieu Baerts (NGI0)" To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: MPTCP Upstream , Paolo Abeni , Geliang Tang , Mat Martineau , "Matthieu Baerts (NGI0)" , Jakub Kicinski , Sasha Levin Subject: [PATCH 6.12.y] mptcp: fix MSG_PEEK stream corruption Date: Tue, 4 Nov 2025 13:15:16 +0100 Message-ID: <20251104121515.1093006-2-matttbe@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <2025110208-pond-pouring-512d@gregkh> References: <2025110208-pond-pouring-512d@gregkh> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4010; i=matttbe@kernel.org; h=from:subject; bh=LOJlpwF16lMiGnFkHh+wBjJqpz1xWbuoVEZ9Jnnsgos=; b=owGbwMvMwCVWo/Th0Gd3rumMp9WSGDI534XMjL2cFM9qWW/yQn3+909LA+O9815kiRwyV+SbW nFj5xmtjlIWBjEuBlkxRRbptsj8mc+reEu8/Cxg5rAygQxh4OIUgInMusvwP3KpAsPCfo1Z/Gom gluZ8jP17JewzF1dz5p14V5fy8R+X0aGOQba0xdcfPH1wu/HWm8WKhvk7F+SE/Tv39uD+7qXJjQ wMgAA X-Developer-Key: i=matttbe@kernel.org; a=openpgp; fpr=E8CB85F76877057A6E27F77AF6B7824F4269A073 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Paolo Abeni [ Upstream commit 8e04ce45a8db7a080220e86e249198fa676b83dc ] If a MSG_PEEK | MSG_WAITALL read operation consumes all the bytes in the receive queue and recvmsg() need to waits for more data - i.e. it's a blocking one - upon arrival of the next packet the MPTCP protocol will start again copying the oldest data present in the receive queue, corrupting the data stream. Address the issue explicitly tracking the peeked sequence number, restarting from the last peeked byte. Fixes: ca4fb892579f ("mptcp: add MSG_PEEK support") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Geliang Tang Tested-by: Geliang Tang Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251028-net-mptcp-send-timeout-v1-2-38ffff5= a9ec8@kernel.org Signed-off-by: Jakub Kicinski [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Matthieu Baerts (NGI0) --- Note: this is the patch Sasha sent for the v6.6 which applies on v6.12 without conflicts. On v6.12, Sasha sent another version with dependences that caused some issues, see: https://lore.kernel.org/bbe84711-95b2-4257-9f01-560b4473a3da@kernel.org --- net/mptcp/protocol.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 5ded0841b159..4798892aa178 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1977,19 +1977,35 @@ static void mptcp_rcv_space_adjust(struct mptcp_soc= k *msk, int copied); =20 static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk, struct msghdr *msg, - size_t len, int flags, + size_t len, int flags, int copied_total, struct scm_timestamping_internal *tss, int *cmsg_flags) { struct sk_buff *skb, *tmp; + int total_data_len =3D 0; int copied =3D 0; =20 skb_queue_walk_safe(&msk->receive_queue, skb, tmp) { - u32 offset =3D MPTCP_SKB_CB(skb)->offset; + u32 delta, offset =3D MPTCP_SKB_CB(skb)->offset; u32 data_len =3D skb->len - offset; - u32 count =3D min_t(size_t, len - copied, data_len); + u32 count; int err; =20 + if (flags & MSG_PEEK) { + /* skip already peeked skbs */ + if (total_data_len + data_len <=3D copied_total) { + total_data_len +=3D data_len; + continue; + } + + /* skip the already peeked data in the current skb */ + delta =3D copied_total - total_data_len; + offset +=3D delta; + data_len -=3D delta; + } + + count =3D min_t(size_t, len - copied, data_len); + if (!(flags & MSG_TRUNC)) { err =3D skb_copy_datagram_msg(skb, offset, msg, count); if (unlikely(err < 0)) { @@ -2006,22 +2022,19 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *= msk, =20 copied +=3D count; =20 - if (count < data_len) { - if (!(flags & MSG_PEEK)) { + if (!(flags & MSG_PEEK)) { + msk->bytes_consumed +=3D count; + if (count < data_len) { MPTCP_SKB_CB(skb)->offset +=3D count; MPTCP_SKB_CB(skb)->map_seq +=3D count; - msk->bytes_consumed +=3D count; + break; } - break; - } =20 - if (!(flags & MSG_PEEK)) { /* we will bulk release the skb memory later */ skb->destructor =3D NULL; WRITE_ONCE(msk->rmem_released, msk->rmem_released + skb->truesize); __skb_unlink(skb, &msk->receive_queue); __kfree_skb(skb); - msk->bytes_consumed +=3D count; } =20 if (copied >=3D len) @@ -2245,7 +2258,8 @@ static int mptcp_recvmsg(struct sock *sk, struct msgh= dr *msg, size_t len, while (copied < len) { int err, bytes_read; =20 - bytes_read =3D __mptcp_recvmsg_mskq(msk, msg, len - copied, flags, &tss,= &cmsg_flags); + bytes_read =3D __mptcp_recvmsg_mskq(msk, msg, len - copied, flags, + copied, &tss, &cmsg_flags); if (unlikely(bytes_read < 0)) { if (!copied) copied =3D bytes_read; --=20 2.51.0