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 using the newly added __mptcp_recvmsg_desc().
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.
v5:
- use the newly added __mptcp_recvmsg_desc.
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 2ebdad6b233d..1a1cfa1ff376 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3985,6 +3985,33 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
return mask;
}
+/*
+ * 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);
+ struct scm_timestamping_internal tss;
+ int flags = 0, cmsg_flags = 0;
+ size_t len = sk->sk_rcvbuf;
+ int copied = 0;
+
+ if (sk->sk_state == TCP_LISTEN)
+ return -ENOTCONN;
+
+ copied = __mptcp_recvmsg_desc(sk, desc, recv_actor,
+ len, flags, &tss, &cmsg_flags);
+ if (copied > 0) {
+ if (skb_queue_empty(&sk->sk_receive_queue))
+ __mptcp_move_skbs(sk);
+ mptcp_cleanup_rbuf(msk, copied);
+ }
+
+ return copied;
+}
+
static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
@@ -4005,6 +4032,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 = {
@@ -4109,6 +4137,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