[net,v2,3/3] mptcp: Use TCP sendmsg/recvmsg for fallback subflows
diff mbox series

Message ID 20200213203836.225812-4-mathew.j.martineau@linux.intel.com
State New
Headers show
Series
  • Untitled series #158434
Related show

Commit Message

Mat Martineau Feb. 13, 2020, 8:38 p.m. UTC
When a connection is in TCP fallback, the MPTCP send and recv functions
are bypassed and calls are passed through to the subflow. The MPTCP
socket is unlocked when this passthrough happens because the send or
receive may block. Using sock_sendmsg() and sock_recvmsg() on the
fallback subflows leads to a race condition because they take struct
socket pointers that can be released by another thread. tcp_sendmsg()
and tcp_recvmsg() use struct sock pointers that are reference counted
and will remain valid after the MPTCP socket lock is released.

Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
---
 net/mptcp/protocol.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 0169e7dfc2d1..fc5d977549f6 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -280,8 +280,13 @@  static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	if (unlikely(ssock)) {
 fallback:
 		pr_debug("fallback passthrough");
+
+		ssk = ssock->sk;
+		sock_hold(ssk);
 		release_sock(sk);
-		ret = sock_sendmsg(ssock, msg);
+		ret = tcp_sendmsg(ssk, msg, msg_data_left(msg));
+		sock_put(ssk);
+
 		return ret >= 0 ? ret + copied : (copied ? copied : ret);
 	}
 
@@ -390,8 +395,13 @@  static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 fallback:
 		pr_debug("fallback-read subflow=%p",
 			 mptcp_subflow_ctx(ssock->sk));
+
+		ssk = ssock->sk;
+		sock_hold(ssk);
 		release_sock(sk);
-		copied = sock_recvmsg(ssock, msg, flags);
+		copied = tcp_recvmsg(ssk, msg, len, nonblock, flags, addr_len);
+		sock_put(ssk);
+
 		return copied;
 	}