From mboxrd@z Thu Jan 1 00:00:00 1970 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 548F72F851 for ; Sun, 2 Nov 2025 20:14:50 +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=1762114490; cv=none; b=bohu3U6Qof2ku5JVlGJXTSlNe1DXdDZlOJJnXg+BPgiT7rddMoQoWBlvaAIltDa+qB3wbygyaepTjKDgoX6nOu7F7HRVwF09ZXCeyLUWoFmDluYtnDwzOe7mB7vX/TzsDUuqJUHl0jTgrAc/snCKZ+ymDhwl/uEmyZHO7wWimSc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762114490; c=relaxed/simple; bh=SMJmWN7fRlh7xgsvqIUv3j37T6QbPuygbKFE+pV8PCg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lOmrTG/kzY8gatbzXNpDvCdbyc54sDxD77YZvpRJ+GREWY+9e8Rc6eNdDNMNlQPQCR0yoJZ/666qEeJXFWt1DCeO7TL8yhRgJAvlB3qSI9wx8pVObvLh8Q/CAh4OYImMNxliOdhGIhf+tzW178Q9eA0tbglDiWf0bkW+JwG0das= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=spLWknCR; 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="spLWknCR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1372FC116D0; Sun, 2 Nov 2025 20:14:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762114489; bh=SMJmWN7fRlh7xgsvqIUv3j37T6QbPuygbKFE+pV8PCg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=spLWknCRAA9VjJZ/cqaA5vLe1oqmY2xtIYouwj7IYM5kGlCghWyd91QqOyYyJ5LuT 4lDoApCXfQCNNHABfWaLtGkfaQ7mSvYhTSNNgJhnSQS3zDpD7c8GUe1YIq00y6+7of aR4K4YBf7EhIFiDz1vYYkLQ2j6co13xr5P9ymfLxdlxErNpG/ar8RI5WYrsPlavCrH mOD4FAKFuFgK85ySx4T2UenBr7U8rdXScnx1KmbRioqOldTDJjfXxd/bdOk8b639OC 5UjT3ptZBCXX4N2eE2Z5/PposZYy+vTQ2vht3nDmublYWV4gTeXunMKS8I+zCbmXhB 3hxH1MncyJ7rg== From: Sasha Levin To: stable@vger.kernel.org Cc: Paolo Abeni , Geliang Tang , Mat Martineau , "Matthieu Baerts (NGI0)" , Jakub Kicinski , Sasha Levin Subject: [PATCH 6.17.y 2/2] mptcp: fix MSG_PEEK stream corruption Date: Sun, 2 Nov 2025 15:14:46 -0500 Message-ID: <20251102201446.3587034-2-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251102201446.3587034-1-sashal@kernel.org> References: <2025110207-deafening-secrecy-80c3@gregkh> <20251102201446.3587034-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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-38ffff5a9ec8@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/mptcp/protocol.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 80ec82d802934..3e055feb0d1e6 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1887,22 +1887,36 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied); -static int __mptcp_recvmsg_mskq(struct sock *sk, - struct msghdr *msg, - size_t len, int flags, +static int __mptcp_recvmsg_mskq(struct sock *sk, struct msghdr *msg, + size_t len, int flags, int copied_total, struct scm_timestamping_internal *tss, int *cmsg_flags) { struct mptcp_sock *msk = mptcp_sk(sk); struct sk_buff *skb, *tmp; + int total_data_len = 0; int copied = 0; skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) { - u32 offset = MPTCP_SKB_CB(skb)->offset; + u32 delta, offset = MPTCP_SKB_CB(skb)->offset; u32 data_len = skb->len - offset; - u32 count = min_t(size_t, len - copied, data_len); + u32 count; int err; + if (flags & MSG_PEEK) { + /* skip already peeked skbs */ + if (total_data_len + data_len <= copied_total) { + total_data_len += data_len; + continue; + } + + /* skip the already peeked data in the current skb */ + delta = copied_total - total_data_len; + offset += delta; + data_len -= delta; + } + + count = min_t(size_t, len - copied, data_len); if (!(flags & MSG_TRUNC)) { err = skb_copy_datagram_msg(skb, offset, msg, count); if (unlikely(err < 0)) { @@ -1919,16 +1933,14 @@ static int __mptcp_recvmsg_mskq(struct sock *sk, copied += count; - if (count < data_len) { - if (!(flags & MSG_PEEK)) { + if (!(flags & MSG_PEEK)) { + msk->bytes_consumed += count; + if (count < data_len) { MPTCP_SKB_CB(skb)->offset += count; MPTCP_SKB_CB(skb)->map_seq += count; - msk->bytes_consumed += count; + break; } - break; - } - if (!(flags & MSG_PEEK)) { /* avoid the indirect call, we know the destructor is sock_rfree */ skb->destructor = NULL; skb->sk = NULL; @@ -1936,7 +1948,6 @@ static int __mptcp_recvmsg_mskq(struct sock *sk, sk_mem_uncharge(sk, skb->truesize); __skb_unlink(skb, &sk->sk_receive_queue); skb_attempt_defer_free(skb); - msk->bytes_consumed += count; } if (copied >= len) @@ -2159,7 +2170,8 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, while (copied < len) { int err, bytes_read; - bytes_read = __mptcp_recvmsg_mskq(sk, msg, len - copied, flags, &tss, &cmsg_flags); + bytes_read = __mptcp_recvmsg_mskq(sk, msg, len - copied, flags, + copied, &tss, &cmsg_flags); if (unlikely(bytes_read < 0)) { if (!copied) copied = bytes_read; -- 2.51.0