From: Geliang Tang <tanggeliang@kylinos.cn>
nvme_tcp_try_recv() needs to call .read_sock interface of struct
proto_ops, but it is not implemented in MPTCP.
This patch implements it with reference to __mptcp_recvmsg_mskq().
v2:
- first check the sk_state (Matt), but not look for the end of the
end of a connection like TCP in __tcp_read_sock():
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
break;
This will cause a use-after-free error:
BUG: KASAN: slab-use-after-free in mptcp_read_sock.
v3:
- Use sk->sk_rcvbuf instead of INT_MAX as the max len.
v4:
- invoke __mptcp_move_skbs.
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 48365d54bc06..fc429d175ede 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3962,6 +3962,67 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
return mask;
}
+static struct sk_buff *mptcp_recv_skb(struct sock *sk)
+{
+ if (skb_queue_empty(&sk->sk_receive_queue))
+ __mptcp_move_skbs(sk);
+
+ return skb_peek(&sk->sk_receive_queue);
+}
+
+/*
+ * Note:
+ * - It is assumed that the socket was locked by the caller.
+ */
+static int mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
+ sk_read_actor_t recv_actor)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ size_t len = sk->sk_rcvbuf;
+ struct sk_buff *skb;
+ int copied = 0;
+
+ if (sk->sk_state == TCP_LISTEN)
+ return -ENOTCONN;
+ while ((skb = mptcp_recv_skb(sk)) != NULL) {
+ u32 offset = MPTCP_SKB_CB(skb)->offset;
+ u32 data_len = skb->len - offset;
+ u32 size = min_t(size_t, len - copied, data_len);
+ int count;
+
+ count = recv_actor(desc, skb, offset, size);
+ if (count <= 0) {
+ if (!copied)
+ copied = count;
+ break;
+ }
+
+ copied += count;
+
+ if (count < data_len) {
+ MPTCP_SKB_CB(skb)->offset += count;
+ MPTCP_SKB_CB(skb)->map_seq += count;
+ msk->bytes_consumed += count;
+ break;
+ }
+
+ mptcp_eat_recv_skb(sk, skb);
+ msk->bytes_consumed += count;
+
+ if (copied >= len)
+ break;
+ }
+
+ mptcp_rcv_space_adjust(msk, copied);
+
+ if (copied > 0) {
+ mptcp_recv_skb(sk);
+ mptcp_cleanup_rbuf(msk, copied);
+ }
+
+ return copied;
+}
+
static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
@@ -3982,6 +4043,7 @@ static const struct proto_ops mptcp_stream_ops = {
.recvmsg = inet_recvmsg,
.mmap = sock_no_mmap,
.set_rcvlowat = mptcp_set_rcvlowat,
+ .read_sock = mptcp_read_sock,
};
static struct inet_protosw mptcp_protosw = {
@@ -4086,6 +4148,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
.compat_ioctl = inet6_compat_ioctl,
#endif
.set_rcvlowat = mptcp_set_rcvlowat,
+ .read_sock = mptcp_read_sock,
};
static struct proto mptcp_v6_prot;
--
2.48.1
Hi Geliang, Thank you for the new version! (Thank you, Paolo, for the previous reviews!) On 07/07/2025 11:34, Geliang Tang wrote: > From: Geliang Tang <tanggeliang@kylinos.cn> > > nvme_tcp_try_recv() needs to call .read_sock interface of struct > proto_ops, but it is not implemented in MPTCP. > > This patch implements it with reference to __mptcp_recvmsg_mskq(). I still think more explanations are needed to help reviewers and developers later, e.g. explaining what this interface is supposed to do, what are the particularities linked to MPTCP and the differences with TCP, why you cannot re-use something already there or the differences with __mptcp_recvmsg_mskq(), etc. > v2: > - first check the sk_state (Matt), but not look for the end of the > end of a connection like TCP in __tcp_read_sock(): > > if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) > break; > > This will cause a use-after-free error: > > BUG: KASAN: slab-use-after-free in mptcp_read_sock. > > v3: > - Use sk->sk_rcvbuf instead of INT_MAX as the max len. > > v4: > - invoke __mptcp_move_skbs. Thank you for the changelog, it is very useful, but please move it in the comment section, under the last Signed-off-by, after a line containing "---": (...) Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- Notes: v2: - (...) Otherwise, the changelog will be part of the commit message when sending this patch to netdev. Same in the other patches. Cheers, Matt -- Sponsored by the NGI0 Core fund.
© 2016 - 2025 Red Hat, Inc.