From nobody Tue May 14 03:29:48 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 2C1EB4C3BC for ; Thu, 8 Feb 2024 20:42:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424979; cv=none; b=epdBgB4Fn+AeJKUORZ5Yuh/0GuKXkuDB1YDzqWxwmjUf/VgwQP81/L/6+ukJKFEJyogNXpDD4jcC2uCrzBGDb4DK5DQgSJp/n2F6EAZ7/gVRXVGztnyMFrj8o6cKfxA62dojbm3QH+8ltrszIyGlrCPeOOexQHP7XjacMtYLZ1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424979; c=relaxed/simple; bh=G3CKvM8wlK6AvhNlAFOQSSpGyZ9LdXN0sN141Ge73kE=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oSL05koDtt7IIW2QRYn+ht/UwfYOOif2kt3bEWXxwcOgwpsUJQBvzAmO5h5/er0qATqm1CtnWE3+tRWmUmFYaRkRWxditL09ghyzGCVQdxvpwLYmvofP3bUvuVyPTux3xH506nCs8VawefU9/fN21M6XBJncsSyZl08RrbkwPn4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=hHWczACD; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="hHWczACD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1707424977; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TUZIjyARMdM26P2VsgyKnw0h+VT5+V8rFaL40RPG22s=; b=hHWczACDTaoRqv6yzkCbNiris4lse14jPb0ORzlUsO5ZFFH1qQ63LpvD7MZT2nYUuD16Zi eqjbsQMWi9viiTiWmCrNdvnvjHeSDqSClMFVmI1BqeBsqSE3kDwu0uI2mbBX0yk/n3em76 nSuBJ1wWXILwjrXNOcwKJ/EwrPz6Rio= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-173-ZjLL_ZePM8uYiZQ9YY0xaA-1; Thu, 08 Feb 2024 15:42:55 -0500 X-MC-Unique: ZjLL_ZePM8uYiZQ9YY0xaA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 923E11C05141 for ; Thu, 8 Feb 2024 20:42:55 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.45.224.247]) by smtp.corp.redhat.com (Postfix) with ESMTP id 21AB4C1596E for ; Thu, 8 Feb 2024 20:42:54 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-net v2 1/4] mptcp: fix lockless access in subflow ULP diag Date: Thu, 8 Feb 2024 21:42:45 +0100 Message-ID: <96f99278110c7ebd0ac401094b367f9bbdf5240f.1707418323.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Since the introduction of the subflow ULP diag interface, the dump callback accessed all the subflow data with lockless. We need either to annotate all the read and write operation accordingly, or acquire the subflow socket lock. Let's do latter, even if slower, to avoid a diffstat havoc. Fixes: 5147dfb50832 ("mptcp: allow dumping subflow context to userspace") Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- note: tls ulp diag has likely the same issue. --- include/net/tcp.h | 2 +- net/mptcp/diag.c | 6 +++++- net/tls/tls_main.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 58e65af74ad1..33bf92dff0af 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -2551,7 +2551,7 @@ struct tcp_ulp_ops { /* cleanup ulp */ void (*release)(struct sock *sk); /* diagnostic */ - int (*get_info)(const struct sock *sk, struct sk_buff *skb); + int (*get_info)(struct sock *sk, struct sk_buff *skb); size_t (*get_info_size)(const struct sock *sk); /* clone ulp */ void (*clone)(const struct request_sock *req, struct sock *newsk, diff --git a/net/mptcp/diag.c b/net/mptcp/diag.c index a536586742f2..e57c5f47f035 100644 --- a/net/mptcp/diag.c +++ b/net/mptcp/diag.c @@ -13,17 +13,19 @@ #include #include "protocol.h" =20 -static int subflow_get_info(const struct sock *sk, struct sk_buff *skb) +static int subflow_get_info(struct sock *sk, struct sk_buff *skb) { struct mptcp_subflow_context *sf; struct nlattr *start; u32 flags =3D 0; + bool slow; int err; =20 start =3D nla_nest_start_noflag(skb, INET_ULP_INFO_MPTCP); if (!start) return -EMSGSIZE; =20 + slow =3D lock_sock_fast(sk); rcu_read_lock(); sf =3D rcu_dereference(inet_csk(sk)->icsk_ulp_data); if (!sf) { @@ -69,11 +71,13 @@ static int subflow_get_info(const struct sock *sk, stru= ct sk_buff *skb) } =20 rcu_read_unlock(); + unlock_sock_fast(sk, slow); nla_nest_end(skb, start); return 0; =20 nla_failure: rcu_read_unlock(); + unlock_sock_fast(sk, slow); nla_nest_cancel(skb, start); return err; } diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 1c2c6800949d..b4674f03d71a 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -1003,7 +1003,7 @@ static u16 tls_user_config(struct tls_context *ctx, b= ool tx) return 0; } =20 -static int tls_get_info(const struct sock *sk, struct sk_buff *skb) +static int tls_get_info(struct sock *sk, struct sk_buff *skb) { u16 version, cipher_type; struct tls_context *ctx; --=20 2.43.0 From nobody Tue May 14 03:29:48 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 CF26B44C73 for ; Thu, 8 Feb 2024 20:42:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424982; cv=none; b=ZnukZegDO1cbpGRXDlZJDebE9vcCNsnmDX0q7yQJj+XPns1oMSTuU1Zw5gFiu8nBORSDut5irZ0PXyA6ylmO0xaWAxonsu0p15ZFvli8DItfcu5JL4+jHdulLjv/MxPEHrw2EZ80YBXEVLjzdPfKMLeLf4fyV2f0OfdQBwt+YWI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424982; c=relaxed/simple; bh=0j1Pi6oTWodpc0qO6dYncTLs/BSZmi4C1l6Zxhf1He8=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MxWlifYz54vykfxflMF2svJwx+dJCjV2sE4RKPldKCOpOlpnBQo0U09liErFr0FuOvMEdUa3VKGcBQ9N5O02xuYsYfQOwkrrRqlj8w3SYmf240wiACLhEgqYYo+mlwOOVlV06mdyQ3ASz9t8A2MhzFXbgZD3ieuWf+XhOiiRfs4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=gRzK1AEH; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="gRzK1AEH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1707424978; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DtiUAjEJwt5ONaoVJWlft7MfK6RbA9Nu/iGQsrbZOgk=; b=gRzK1AEHeRysfxSJX/SeMPMIFJ1glUe4uPrX/b7MYxneGjkMihgK/UTTWy9phXY9Ln2hXa XSk1P/igBnOSNBazb8Mo2+Gh40s4iHNLb78V08YAHppKkdwKgOIne+eCWCUXnMcH/+TTsR Oivdunfd06Ox0dnYE2cnjIXKEHGb6wk= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-19-uhNzJkiBPaaRV8vPuvJvFQ-1; Thu, 08 Feb 2024 15:42:56 -0500 X-MC-Unique: uhNzJkiBPaaRV8vPuvJvFQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 581483869143 for ; Thu, 8 Feb 2024 20:42:56 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.45.224.247]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC391C08EF7 for ; Thu, 8 Feb 2024 20:42:55 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-net v2 2/4] mptcp: fix data races on local_id Date: Thu, 8 Feb 2024 21:42:46 +0100 Message-ID: <6842c91dfceda8a883a90aa57cbb4df4c20908a5.1707418323.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" The local address id is accessed lockless by the NL PM, add all the required ONCE annotation. There is a caveat: the local id can be initialized late in the subflow life-cycle, and its validity is controlled by the local_id_valid flag. Remove such flag and encode the validity in the local_id field itself with negative value before initialization. That allows accessing the field consistently with a single read operation. Fixes: 0ee4261a3681 ("mptcp: implement mptcp_pm_remove_subflow") Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- v1 -> v2: - get_local_id() return u8 - use extend helper usage in more places - READ_ONCE() in pm_userspace --- net/mptcp/diag.c | 2 +- net/mptcp/pm_netlink.c | 6 +++--- net/mptcp/pm_userspace.c | 2 +- net/mptcp/protocol.c | 2 +- net/mptcp/protocol.h | 15 ++++++++++++--- net/mptcp/subflow.c | 9 +++++---- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/net/mptcp/diag.c b/net/mptcp/diag.c index e57c5f47f035..6ff6f14674aa 100644 --- a/net/mptcp/diag.c +++ b/net/mptcp/diag.c @@ -65,7 +65,7 @@ static int subflow_get_info(struct sock *sk, struct sk_bu= ff *skb) sf->map_data_len) || nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_FLAGS, flags) || nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_REM, sf->remote_id) || - nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, sf->local_id)) { + nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, subflow_get_local_id(sf)))= { err =3D -EMSGSIZE; goto nla_failure; } diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index d9ad45959219..1745678d3009 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -800,7 +800,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp= _sock *msk, mptcp_for_each_subflow_safe(msk, subflow, tmp) { struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); int how =3D RCV_SHUTDOWN | SEND_SHUTDOWN; - u8 id =3D subflow->local_id; + u8 id =3D subflow_get_local_id(subflow); =20 if (rm_type =3D=3D MPTCP_MIB_RMADDR && subflow->remote_id !=3D rm_id) continue; @@ -809,7 +809,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp= _sock *msk, =20 pr_debug(" -> %s rm_list_ids[%d]=3D%u local_id=3D%u remote_id=3D%u mpc_= id=3D%u", rm_type =3D=3D MPTCP_MIB_RMADDR ? "address" : "subflow", - i, rm_id, subflow->local_id, subflow->remote_id, + i, rm_id, id, subflow->remote_id, msk->mpc_endpoint_id); spin_unlock_bh(&msk->pm.lock); mptcp_subflow_shutdown(sk, ssk, how); @@ -1980,7 +1980,7 @@ static int mptcp_event_add_subflow(struct sk_buff *sk= b, const struct sock *ssk) if (WARN_ON_ONCE(!sf)) return -EINVAL; =20 - if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, sf->local_id)) + if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf))) return -EMSGSIZE; =20 if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id)) diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index 4f3901d5b8ef..70cca1318575 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -233,7 +233,7 @@ static int mptcp_userspace_pm_remove_id_zero_address(st= ruct mptcp_sock *msk, =20 lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { - if (subflow->local_id =3D=3D 0) { + if (READ_ONCE(subflow->local_id) =3D=3D 0) { has_id_0 =3D true; break; } diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index a8a94b34a51e..626fb4907381 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -85,7 +85,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) subflow->subflow_id =3D msk->subflow_id++; =20 /* This is the first subflow, always with id 0 */ - subflow->local_id_valid =3D 1; + WRITE_ONCE(subflow->local_id, 0); mptcp_sock_graft(msk->first, sk->sk_socket); iput(SOCK_INODE(ssock)); =20 diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index de04b97e8dd1..62b84cc6f35e 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -493,10 +493,9 @@ struct mptcp_subflow_context { remote_key_valid : 1, /* received the peer key from */ disposable : 1, /* ctx can be free at ulp release time */ stale : 1, /* unable to snd/rcv data, do not use for xmit */ - local_id_valid : 1, /* local_id is correctly initialized */ valid_csum_seen : 1, /* at least one csum validated */ is_mptfo : 1, /* subflow is doing TFO */ - __unused : 9; + __unused : 10; bool data_avail; bool scheduled; u32 remote_nonce; @@ -507,7 +506,7 @@ struct mptcp_subflow_context { u8 hmac[MPTCPOPT_HMAC_LEN]; /* MPJ subflow only */ u64 iasn; /* initial ack sequence number, MPC subflows only */ }; - u8 local_id; + s16 local_id; /* if negative not initialized yet */ u8 remote_id; u8 reset_seen:1; u8 reset_transient:1; @@ -558,6 +557,7 @@ mptcp_subflow_ctx_reset(struct mptcp_subflow_context *s= ubflow) { memset(&subflow->reset, 0, sizeof(subflow->reset)); subflow->request_mptcp =3D 1; + WRITE_ONCE(subflow->local_id, -1); } =20 static inline u64 @@ -1064,6 +1064,15 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, st= ruct sock_common *skc); int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_inf= o *skc); int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_a= ddr_info *skc); =20 +static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *= subflow) +{ + int local_id =3D READ_ONCE(subflow->local_id); + + if (local_id < 0) + return 0; + return local_id; +} + void __init mptcp_pm_nl_init(void); void mptcp_pm_nl_work(struct mptcp_sock *msk); void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 02dab0669cfc..068784d3e748 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -578,8 +578,8 @@ static void subflow_finish_connect(struct sock *sk, con= st struct sk_buff *skb) =20 static void subflow_set_local_id(struct mptcp_subflow_context *subflow, in= t local_id) { - subflow->local_id =3D local_id; - subflow->local_id_valid =3D 1; + WARN_ON_ONCE(local_id < 0 || local_id > 255); + WRITE_ONCE(subflow->local_id, local_id); } =20 static int subflow_chk_local_id(struct sock *sk) @@ -588,7 +588,7 @@ static int subflow_chk_local_id(struct sock *sk) struct mptcp_sock *msk =3D mptcp_sk(subflow->conn); int err; =20 - if (likely(subflow->local_id_valid)) + if (likely(subflow->local_id >=3D 0)) return 0; =20 err =3D mptcp_pm_get_local_id(msk, (struct sock_common *)sk); @@ -1733,6 +1733,7 @@ static struct mptcp_subflow_context *subflow_create_c= tx(struct sock *sk, pr_debug("subflow=3D%p", ctx); =20 ctx->tcp_sock =3D sk; + WRITE_ONCE(ctx->local_id, -1); =20 return ctx; } @@ -1968,7 +1969,7 @@ static void subflow_ulp_clone(const struct request_so= ck *req, new_ctx->idsn =3D subflow_req->idsn; =20 /* this is the first subflow, id is always 0 */ - new_ctx->local_id_valid =3D 1; + subflow_set_local_id(new_ctx, 0); } else if (subflow_req->mp_join) { new_ctx->ssn_offset =3D subflow_req->ssn_offset; new_ctx->mp_join =3D 1; --=20 2.43.0 From nobody Tue May 14 03:29:48 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 DF18A44C7A for ; Thu, 8 Feb 2024 20:42:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424981; cv=none; b=EliJ65jZEmY5JLsBA+xyzNjMNmk4IQiCGvSQ5XazbHTNvpOEgXnutPa7jTMqj+O/EIg6FdGUHdHt16o0DfNd+Sbg7tDcGzgUQSt8th3LyetjilvHLwbWEr7LIbUeuyH4GqCYEpBdZdxPildPzbeUK6CY+Im/zay7fjEzakFZA2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424981; c=relaxed/simple; bh=7NhgPGcQu1X7ymLrQs7vbtvLRDYa8h8jN/7QeG85KHM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OiTWf9KwUWjwaAveizxwH2We/Do9mNSg8fdgIpxkqAcm8i+O/5rMmL9DQwQezxdhnab5i6uo5uLDNzJVGucVh4fbs8L3NMVru6/YedhJo75080aDibaMnHZp5yOwdpIYjWdw7PloMxisI9fRvxinOROzqXeNbB78ZPZTONLPfLg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=cv2tq85o; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="cv2tq85o" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1707424978; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jjHxco2L7R6JsQwZJyiwtvYn2WmUpjJJIdm5+eEbGk0=; b=cv2tq85o0RbiZUn4F+yxn5ZlTc2RXE4RYnZRg00TkHgeOEMLEyLByjtLiYKM9BD4Doug1C cR4ZBFBpSt75FFEoWXEX6xWnidIhNaL1jzuRHOJmwaFIyUDppHa4OTWxCTWbZhJquE6sme 5mnSTCYdUPPRjCF0S2CAbvoji0hyUn0= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-60-9M2r5yBQO1Wh0zJFAV6iIQ-1; Thu, 08 Feb 2024 15:42:57 -0500 X-MC-Unique: 9M2r5yBQO1Wh0zJFAV6iIQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1EC4F3C0C488 for ; Thu, 8 Feb 2024 20:42:57 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.45.224.247]) by smtp.corp.redhat.com (Postfix) with ESMTP id A1E71C08EF7 for ; Thu, 8 Feb 2024 20:42:56 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-net v2 3/4] mptcp: fix data races on remote_id Date: Thu, 8 Feb 2024 21:42:47 +0100 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Similar to the previous patch, address the data race on remote_id, adding the suitable ONCE annotations. Fixes: bedee0b56113 ("mptcp: address lookup improvements") Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- v1 -> v2: - srm_id -> remote_id --- net/mptcp/pm_netlink.c | 8 ++++---- net/mptcp/subflow.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 1745678d3009..a88cbe266a90 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -443,7 +443,7 @@ static unsigned int fill_remote_addresses_vec(struct mp= tcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { ssk =3D mptcp_subflow_tcp_sock(subflow); remote_address((struct sock_common *)ssk, &addrs[i]); - addrs[i].id =3D subflow->remote_id; + addrs[i].id =3D READ_ONCE(subflow->remote_id); if (deny_id0 && !addrs[i].id) continue; =20 @@ -799,18 +799,18 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mpt= cp_sock *msk, =20 mptcp_for_each_subflow_safe(msk, subflow, tmp) { struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + u8 remote_id =3D READ_ONCE(subflow->remote_id); int how =3D RCV_SHUTDOWN | SEND_SHUTDOWN; u8 id =3D subflow_get_local_id(subflow); =20 - if (rm_type =3D=3D MPTCP_MIB_RMADDR && subflow->remote_id !=3D rm_id) + if (rm_type =3D=3D MPTCP_MIB_RMADDR && remote_id !=3D rm_id) continue; if (rm_type =3D=3D MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id= , rm_id)) continue; =20 pr_debug(" -> %s rm_list_ids[%d]=3D%u local_id=3D%u remote_id=3D%u mpc_= id=3D%u", rm_type =3D=3D MPTCP_MIB_RMADDR ? "address" : "subflow", - i, rm_id, id, subflow->remote_id, - msk->mpc_endpoint_id); + i, rm_id, id, remote_id, msk->mpc_endpoint_id); spin_unlock_bh(&msk->pm.lock); mptcp_subflow_shutdown(sk, ssk, how); =20 diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 068784d3e748..6403c56f2902 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -536,7 +536,7 @@ static void subflow_finish_connect(struct sock *sk, con= st struct sk_buff *skb) subflow->backup =3D mp_opt.backup; subflow->thmac =3D mp_opt.thmac; subflow->remote_nonce =3D mp_opt.nonce; - subflow->remote_id =3D mp_opt.join_id; + WRITE_ONCE(subflow->remote_id, mp_opt.join_id); pr_debug("subflow=3D%p, thmac=3D%llu, remote_nonce=3D%u backup=3D%d", subflow, subflow->thmac, subflow->remote_nonce, subflow->backup); @@ -1569,7 +1569,7 @@ int __mptcp_subflow_connect(struct sock *sk, const st= ruct mptcp_addr_info *loc, pr_debug("msk=3D%p remote_token=3D%u local_id=3D%d remote_id=3D%d", msk, remote_token, local_id, remote_id); subflow->remote_token =3D remote_token; - subflow->remote_id =3D remote_id; + WRITE_ONCE(subflow->remote_id, remote_id); subflow->request_join =3D 1; subflow->request_bkup =3D !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP); subflow->subflow_id =3D msk->subflow_id++; @@ -1976,7 +1976,7 @@ static void subflow_ulp_clone(const struct request_so= ck *req, new_ctx->fully_established =3D 1; new_ctx->remote_key_valid =3D 1; new_ctx->backup =3D subflow_req->backup; - new_ctx->remote_id =3D subflow_req->remote_id; + WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id); new_ctx->token =3D subflow_req->token; new_ctx->thmac =3D subflow_req->thmac; =20 --=20 2.43.0 From nobody Tue May 14 03:29:48 2024 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 9457445BFB for ; Thu, 8 Feb 2024 20:43:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424982; cv=none; b=MtJzivVOafxwxRtHCfvj61qweyXwEynAl7ufqubKwQ2tbHHPoOQCoHjRmf5GGF4bbc8jxZqyOEyLIS5Ogr3n484Iy9eNPZtH2AbCsw6xkJJ1krj7yrnHZzI/LUlsqXBh6I5b3s7yL0fxrM1FJh1OELaBoYDyiib1h7rN6xsOujY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707424982; c=relaxed/simple; bh=RArSk1MaaMQE6RStJlMmMFaMYVYDlkHtZ/Xi/67mM3g=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Xei5dX9co+LveyMq1WroqneYXMKR1IoutT0Q9+f/UtPfBdbRp/DBE8put70ncfUTrlHeESsyPjgzpOxlnd74ZpnuYQZQALXm6n8Dhv2W0hRNkLj6XaTuM0Lt161KYwzL66FaMiXW4zgSEWpLXDo4RD3uQNvGSqmsvM3hlzQc/+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=OsxZWMFq; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="OsxZWMFq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1707424979; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=A2LuycBoDHZtsKufyTqMIKCNfjKKqgGophSzKH5Ey3c=; b=OsxZWMFql9xTGqfR0iR55oha9GoY/4YkGAaSBxlHSRO4xBCd1mVmyMET1G0d7P6jYvgKuM Nj/1G2XDOlkSj7EOD7cJEZxU3R6AkNgeNllar8txuDVEFQTbfBFHo5Gi+1lsvVFdgmBKQs or5gDEBCd/tLK2nBx5eEYj4Oc4BPMhI= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-375-VZa3NCWRPimgahF6H8kc0w-1; Thu, 08 Feb 2024 15:42:58 -0500 X-MC-Unique: VZa3NCWRPimgahF6H8kc0w-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D95463C0C484 for ; Thu, 8 Feb 2024 20:42:57 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.45.224.247]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6864BC08EF7 for ; Thu, 8 Feb 2024 20:42:57 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH mptcp-net v2 4/4] mptcp: fix duplicate subflow creation Date: Thu, 8 Feb 2024 21:42:48 +0100 Message-ID: <65ea8b9d71895455ded0ed44d74e0de0e2c2481e.1707418323.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Fullmesh endpoints could end-up unexpectedly generating duplicate subflows - same local and remote addresses - when multiple incoming ADD_ADDR are processed before the PM creates the subflow for the local endpoints. Address the issue explicitly checking for duplicates at subflow creation time. To avoid a quadratic computational complexity, track the unavailable remote address ids in a temporary bitmap and initialize such bitmap with the remote ids of all the existing subflows matching the local address currently processed. The above allows additionally replacing the existing code checking for duplicate entry in the current set with a simple bit test operation. Fixes: 2843ff6f36db ("mptcp: remote addresses fullmesh") Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/435 Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- v1 -> v2: - forbit -> forbid Note that there is no problem for the opposite event sequence. --- net/mptcp/pm_netlink.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index a88cbe266a90..b87d802da028 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -396,19 +396,6 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk) } } =20 -static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, uns= igned int nr, - const struct mptcp_addr_info *addr) -{ - int i; - - for (i =3D 0; i < nr; i++) { - if (addrs[i].id =3D=3D addr->id) - return true; - } - - return false; -} - /* Fill all the remote addresses into the array addrs[], * and return the array size. */ @@ -440,6 +427,16 @@ static unsigned int fill_remote_addresses_vec(struct m= ptcp_sock *msk, msk->pm.subflows++; addrs[i++] =3D remote; } else { + DECLARE_BITMAP(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1); + + /* Forbid creation of new subflows matching existing + * ones, possibly already created by incoming ADD_ADDR + */ + bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1); + mptcp_for_each_subflow(msk, subflow) + if (READ_ONCE(subflow->local_id) =3D=3D local->id) + __set_bit(subflow->remote_id, unavail_id); + mptcp_for_each_subflow(msk, subflow) { ssk =3D mptcp_subflow_tcp_sock(subflow); remote_address((struct sock_common *)ssk, &addrs[i]); @@ -447,11 +444,17 @@ static unsigned int fill_remote_addresses_vec(struct = mptcp_sock *msk, if (deny_id0 && !addrs[i].id) continue; =20 + if (test_bit(addrs[i].id, unavail_id)) + continue; + if (!mptcp_pm_addr_families_match(sk, local, &addrs[i])) continue; =20 - if (!lookup_address_in_vec(addrs, i, &addrs[i]) && - msk->pm.subflows < subflows_max) { + if (msk->pm.subflows < subflows_max) { + /* forbid creating multiple address towards + * this id + */ + __set_bit(addrs[i].id, unavail_id); msk->pm.subflows++; i++; } --=20 2.43.0