From patchwork Thu Feb 13 20:38:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mat Martineau X-Patchwork-Id: 1237721 X-Patchwork-Delegate: mathew.j.martineau@linux.intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.01.org (client-ip=198.145.21.10; helo=ml01.01.org; envelope-from=mptcp-bounces@lists.01.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.intel.com Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48JSz64gWCz9sRG for ; Fri, 14 Feb 2020 07:38:58 +1100 (AEDT) Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id CD35C10FC33FE; Thu, 13 Feb 2020 12:42:11 -0800 (PST) Received-SPF: Pass (helo) identity=helo; client-ip=192.55.52.136; helo=mga12.intel.com; envelope-from=mathew.j.martineau@linux.intel.com; receiver= Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id EDE5310FC33F0 for ; Thu, 13 Feb 2020 12:42:08 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Feb 2020 12:38:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,437,1574150400"; d="scan'208";a="281626042" Received: from mjmartin-nuc02.mjmartin-nuc02 (HELO mjmartin-nuc02.sea.intel.com) ([10.251.2.84]) by FMSMGA003.fm.intel.com with ESMTP; 13 Feb 2020 12:38:51 -0800 From: Mat Martineau To: mptcp@lists.01.org Cc: Mat Martineau Date: Thu, 13 Feb 2020 12:38:36 -0800 Message-Id: <20200213203836.225812-4-mathew.j.martineau@linux.intel.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200213203836.225812-1-mathew.j.martineau@linux.intel.com> References: <20200213203836.225812-1-mathew.j.martineau@linux.intel.com> MIME-Version: 1.0 Message-ID-Hash: VGLLRJSL4327QZITS2TPIH3SPTWDILU6 X-Message-ID-Hash: VGLLRJSL4327QZITS2TPIH3SPTWDILU6 X-MailFrom: mathew.j.martineau@linux.intel.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.1.1 Precedence: list Subject: [MPTCP] [PATCH net v2 3/3] mptcp: Use TCP sendmsg/recvmsg for fallback subflows List-Id: Discussions regarding MPTCP upstreaming Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: 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 --- net/mptcp/protocol.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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; }