From nobody Sat Aug 15 20:30:36 2026 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 245CE30FF30 for ; Wed, 12 Aug 2026 06:56:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786517766; cv=none; b=pdyzysZA1sOMBnLZtG5iyP9Pfjrt2F4kL7zBG/LNQCCcK6quaxYYMHoygibFCLqYElccZq+2z41IKssEAPWdqCefMZW1jA8a8F/h6TRW14W0+jBS8CwLmDgnDGK4iK+v6s+9egtN+ty55U0C0lNcx071gW9vsCQXYBsmypJFAC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786517766; c=relaxed/simple; bh=JnhSd2jLP4X3eR3UTW97+LOiFbBUNUSEHSCyoIJ1NbU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hRTfyhvH/c94yfj3bOlx3Qg0/ZTOsVL46BBkYfYSXg0cZFC5Bprt501ScVvy+gl+zw/fUreOAy1CPP31Az9BZr/yu89AFMdQsVnifdpyuDTRmMWeIWq+UiKSpiduCLZ8y2A1pMhdf1bVVGzd59i7NWGZPoVa8vBn7vuAaGMh/Wg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai; spf=pass smtp.mailfrom=nebusec.ai; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b=l+wRFMVy; arc=none smtp.client-ip=209.85.216.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b="l+wRFMVy" Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-38dd55ad76cso778010a91.1 for ; Tue, 11 Aug 2026 23:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1786517764; x=1787122564; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=zUpOfz+sm9tkkgAFwKxKf/LC6hjxRNWvUZB8avg2+jk=; b=l+wRFMVySuv3RkaFSntB5AMSpZJXX06XYD5ZYol5CX0NQuu6EcwEFUGLwBo1VF3/2R 8NP00oGZZdcYKGf4f1OKSEjuSd7ff9Ia6j1O71BkeJVhPLMvCdB7aJ50i4O7e1EoEvrk bo8Vc3AU/RR+uWrlmWoXXGt6PMf/3948W/E5D7ayZgAlpNmZDmsOQ3Klqj6hMHpkKjXO en/KU0uH9+nw3z0TIspmQGdrJ7PyOrlJA1DCAsg8UOqxRR1ttltU2PkkdoC/VBcjcbxr tn9O9RFAirtLMwykSrQX9aplTAZWQVllJoXzSZuGSwXPqiw74ERellP+9flyBR8X6xBp Shog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786517764; x=1787122564; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=zUpOfz+sm9tkkgAFwKxKf/LC6hjxRNWvUZB8avg2+jk=; b=Fc/tPYeKtWWlMcWOJsTFDIe8XBTc1ASUN/hn1BR6Oj83K1FRpUZpr5siQTUIGCFHLu yuSobRPKddBjXCo/N1+Anl0jVfkRQVBC/pzyIEwELorCdAx3vxz4onlBOB3d5II/LXmb gpKT8eptGNSjjPpCMv0Fshv3ZVFwDqo5ONDHvqb81oRMxyNjZGNJM6BfmIfchK4vu8QQ nCudOAaW2qZQwEU8eij7GtaRniB7dRTcHwr4PRmIbrJrOWtb8ReN1PcGZjNF+Ur2TngH 88f8VBbvpVzlFWOaRarQry7JSFRLOYx9XgdMXl9fJ0SNpj2olMziMwHDUU/8+Ho7AAE8 AUbQ== X-Forwarded-Encrypted: i=1; AHgh+RpyGY/h3jzsKV9NnZlLKk3gjKshJybvLx9kTT5/tZIF6UKH37zdzQZolaQn6C+oCC1d81V5vw==@lists.linux.dev X-Gm-Message-State: AOJu0Yx/r5kXMH7rbn9izY8KBbeVob1pbkZIsCTU9hz7j3yp66RAJi7f mrtWJvIPyVuEaJPT2sbjvpyaiOKWdCTjRjBMd/xZmqBpgwwtxYS6WRESfEw7rD9OclzI X-Gm-Gg: AR+sD12O/1tAgJck1LHKcrsoOU0ct0C99+Gq/1WQTnk9HQ69t31VIMJf6cUzvW6Q1Fo vg3F/WMQxl0kmsoOYGEdRZ7V+8tzYbYlK5PjRkhrrAZsXqHNStth75IIosyq68AJ5nr7UQZMQ6z 3e7KwWAnjpi1AknLKTxKMh+Ou4bQtiJFO/7uJzk9yoGzoEE3sgx7pop6B3vhrHuXbhOXl6eY9Au T/mGV9a6vBQezQloFyRpNML9KfgbRVg5qT9+9NphN78iy2SYlPprWHmWnrj3g15/UsLvetahdUt on8Q+3gurcxW/mB4a6rqTQBUguUJmMI1HwsplHGWjUtUwuEDliXagB/Aju13LgIL3DggbPzCTk+ OQoYXzFkmDenSHUNPl9Ch60JAj/NV9go2kLkwslr1Et4xs0P4PXn3FIX39Ta61IxHziGgG9Hwol 5ab3d7A00cPm9/3pJdkTMiGzcGNVckrFq+DYClFBoKGBvRsc2i0ARY8GptzcWuMJ/X5PDPAg== X-Received: by 2002:a17:90b:4c4a:b0:386:ca4b:16a9 with SMTP id 98e67ed59e1d1-39302bc9c67mr1076959a91.16.1786517764333; Tue, 11 Aug 2026 23:56:04 -0700 (PDT) Received: from enjou-Legion-Y7000P-2019 ([165.232.167.5]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-392f8d00067sm2546980a91.12.2026.08.11.23.55.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 23:56:03 -0700 (PDT) From: Ren Wei To: netdev@vger.kernel.org, mptcp@lists.linux.dev Cc: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, ncardwell@google.com, kuniyu@google.com, kafai@fb.com, daniel@iogearbox.net, kylebot@openai.com, david.lee@trailofbits.com, vega@nebusec.ai, caoruide123@gmail.com, weir@nebusec.ai, sashiko-bot@kernel.org Subject: [PATCH net v4 1/2] mptcp: hold MP_JOIN msk ref when cloning reqsk Date: Wed, 12 Aug 2026 14:55:45 +0800 Message-ID: X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ruide Cao TCP request migration clones pending request sockets with inet_reqsk_clone(). For MPTCP MP_JOIN requests this byte-copies subflow_req->msk, but the clone does not take its own reference. The original and cloned request can consequently drop the same msk reference from subflow_req_destructor(), leaving one request with a dangling pointer after the other is released. Add an MPTCP clone helper on the TCP request migration path and let cloned subflow requests grab their own msk reference when one is present. The clone's normal destructor balances this reference on both successful migration and failed clone/insert paths. Fixes: c905dee62232 ("tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitt= ing SYN+ACKs.") Cc: stable@vger.kernel.org Reported-by: Kyle Zeng Reported-by: David Lee Closes: https://lore.kernel.org/all/20260804095051.715355-1-david.lee@trail= ofbits.com/ Reported-by: Vega Assisted-by: Codex:gpt-5.4 Signed-off-by: Ruide Cao Signed-off-by: Ren Wei --- include/net/mptcp.h | 7 +++++++ net/ipv4/inet_connection_sock.c | 4 ++++ net/mptcp/subflow.c | 11 +++++++++++ 3 files changed, 22 insertions(+) diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 71b9fc5a5796..0a02ac1ed22d 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -223,6 +223,8 @@ int mptcp_subflow_init_cookie_req(struct request_sock *= req, struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_o= ps *ops, struct sock *sk_listener, bool attach_listener); +void mptcp_subflow_reqsk_clone(struct request_sock *req, + struct request_sock *new_req); =20 __be32 mptcp_get_reset_option(const struct sk_buff *skb); =20 @@ -309,6 +311,11 @@ static inline struct request_sock *mptcp_subflow_reqsk= _alloc(const struct reques return NULL; } =20 +static inline void mptcp_subflow_reqsk_clone(struct request_sock *req, + struct request_sock *new_req) +{ +} + static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { retu= rn htonl(0u); } =20 static inline void mptcp_active_detect_blackhole(struct sock *sk, bool exp= ired) { } diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_soc= k.c index 6257459bcee2..896f472dcba2 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include =20 @@ -961,6 +962,9 @@ static struct request_sock *inet_reqsk_clone(struct req= uest_sock *req, rcu_assign_pointer(tcp_sk(nreq->sk)->fastopen_rsk, nreq); } =20 + if (rsk_is_mptcp(req)) + mptcp_subflow_reqsk_clone(req, nreq); + return nreq; } =20 diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index e1f20ff8fdb4..8f8e1229766d 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -47,6 +47,17 @@ static void subflow_req_destructor(struct request_sock *= req) mptcp_token_destroy_request(req); } =20 +void mptcp_subflow_reqsk_clone(struct request_sock *req, + struct request_sock *new_req) +{ + struct mptcp_subflow_request_sock *subflow_req; + + subflow_req =3D mptcp_subflow_rsk(new_req); + + if (subflow_req->msk) + sock_hold((struct sock *)subflow_req->msk); +} + static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonc= e2, void *hmac) { --=20 2.43.0 From nobody Sat Aug 15 20:30:36 2026 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 550DA30FF30 for ; Wed, 12 Aug 2026 06:56:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786517779; cv=none; b=mSJ34V5LIZnKuGFxjv37tF65xFt6TUE5S/GqW1N7CRj7WSbw6XRNc3WkhccChoisXRdKXx2i2rI8lWZlSNel4w0fDxZKxD5+NiTy6lSQkO8Kqo/DSBA86NcalzGSSnqk5pvl3zHwrbdY6ihaQDMLtr1oAivNTP2SYQQtJLt0nr0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786517779; c=relaxed/simple; bh=epeMBQ1VCWKYkFcqnC7mbhGl85XSUyqpcxq2gdj6ACc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JLdRgwjDRliWZ4Yp8pocsju1cM9+T9YaxdM0yl9SVno0cPnTKnjz7IHrglDTmvkJhiBZ2v1DrlesLgeZy6+UDykiuvB2ZYPfxyEW/9VKndeF47Y5aymZ10AbiWcUPfE7qUwehNoSmZqohE+b7sbqj36vJ8HEZ9EvojXDzszj54M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai; spf=pass smtp.mailfrom=nebusec.ai; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b=nLlVBbkP; arc=none smtp.client-ip=209.85.216.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b="nLlVBbkP" Received: by mail-pj1-f49.google.com with SMTP id 98e67ed59e1d1-38dfe7eb825so647145a91.0 for ; Tue, 11 Aug 2026 23:56:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1786517778; x=1787122578; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=2435U7AuiFlclz3ovDhPH4Evn/dXBwX9yd7aszzBj8A=; b=nLlVBbkP+8lQvdzpPErQ/vPHm3S4n0+F7Zhjal+nbJzsVaqmvnh5LjrqPcUJ7FCEIp Vl/fceFbjxyl5sNikCSnAFcbSM5NmGuwH55F/VbiUFBria0u9gsovFKSDL1jTkP5MheN 9EY2kJCb/DLGeq1dgBG7ABU7iZr9uX122s2bokjzbrrYi2dxtCQ96Mnp3F98pMDGaN4b gKgILgT9wxoc8w/jOAwU4NRuni1v/pUwNAwOfkjVN9TDc8Sajxq3RadgQyPVMXEU3I4s V2P2ixT7qWkG4GnF07/n+mELaDiQV8xSHyHQ9ouf+a46ct8ybyDfVxiTLCJjL5ChAnzw n0tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786517778; x=1787122578; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=2435U7AuiFlclz3ovDhPH4Evn/dXBwX9yd7aszzBj8A=; b=dH9mKEY6iHyCxHHCRLzPpGi1vp52VBDg6wQdKJF4nK79llkkIwEPa/vq0nxK1q2cnA 248BY9msrASfDb20u3xRm0QD6vJQhA3Xq1kS4lqbYbbkaw0kjYBUCZzOlwBAT1bWmmu8 AYvitE1OIFvua/cWe8Of1oxbhwdENYZLvk/uvqj/Zn/wCBF4i4HLO4Ok/Vp8QFl5f4y1 dno0Xuu8Lb2ZcgNQrbmBcXLe2DnZj7bEkkDM3+Dbun67ISb2wCX8h2h3QJlPl2C9ism1 wQj4YZRdVWaoa4cIJAUPwEUV85/EGxIjFqAUjgRQ2TN8a1pKY+aQ0/6qAnqxb6LUQ37a YOcw== X-Forwarded-Encrypted: i=1; AHgh+Rptw17/Rf2I5LJTZe9lFaPbwY9OamXevO9mqjc0PGVHKoLG5NfobOGTC5eEG279eFj2pP8DQQ==@lists.linux.dev X-Gm-Message-State: AOJu0YyVQPwm5AO8F/PoizuUPt+VxseAE9JB9dFoPS1tz38uJp6FF07i wxy+IhvpYyGzIVlawtQml8gOdH43ICxh+KRQVcz+w4ZLucMJD+vOJfxEShDJD7NISOvo X-Gm-Gg: AR+sD11VPh8h5dM2H16zzMio3JDcDZJ2wbXF62Ss//6hiZ4VkkTF3nU/QlTinOwR+hC UAtd8/+g/legHfYvl0ctWDEAmNiYfFKVwtoivqQvsCgyu3CMYvXAQY8oR0ua4/shyweCw51Mj9t 3/FaAj1WI8K85pBG1EtkWnnyZROsOmSzII9JMLDRv/2+gcaxNmw/CJuvIghVCqc1PI/LfPOVIPe jBC+hG2grXGje3rVxgz++HMO8RC/ibfPGm1P6X1274dEGObVAyxLZ5VyOd33pNGjkFqc6Ykyzb0 MzaV2F/s4QTNsKZDMTc8LPqwQhED4gaPm7+B8an8sKYEl7gFnYcEku4KctPrqiAaIA1qeOh6gTN CuTzqOmBXNxbxlgchPjFVp8/jU+VPuV/7DWOm0zU1KIXAfr8rNRm9wDZEkP8WrFeJYn0P6uDxzU D8mGFDb/TTwN8PlOJgyM8wK5Acnm5OpPPXl0Y83P66a4t8aMD0SSk9ZjiycubYcHjrhAfU1A== X-Received: by 2002:a17:90b:4cd1:b0:38e:ad9d:1151 with SMTP id 98e67ed59e1d1-393012cee12mr3299614a91.4.1786517777555; Tue, 11 Aug 2026 23:56:17 -0700 (PDT) Received: from enjou-Legion-Y7000P-2019 ([165.232.167.5]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-392f8d00067sm2546980a91.12.2026.08.11.23.56.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 23:56:17 -0700 (PDT) From: Ren Wei To: netdev@vger.kernel.org, mptcp@lists.linux.dev Cc: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, ncardwell@google.com, kuniyu@google.com, kafai@fb.com, daniel@iogearbox.net, kylebot@openai.com, david.lee@trailofbits.com, vega@nebusec.ai, caoruide123@gmail.com, weir@nebusec.ai, sashiko-bot@kernel.org Subject: [PATCH net v4 2/2] mptcp: fix MP_CAPABLE token migration when cloning reqsk Date: Wed, 12 Aug 2026 14:55:46 +0800 Message-ID: <6abadc83940143e099fa3b54ec6dea2fb95da090.1786497414.git.yuantan098@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ruide Cao TCP request migration clones pending request sockets with inet_reqsk_clone(). For MPTCP MP_CAPABLE requests this byte-copies the token_node hlist state into the clone even though the token table still names the original request. Moving the token only after inet_ehash_insert() succeeds leaves a window where the cloned request is already globally visible from the ehash but the token table still points at the original request. Reordering the move after clone but before ehash exposure closes that window, but concurrent RX can still race on the old request and observe that the token was already moved. Move MP_CAPABLE token request ownership during MPTCP request cloning under the token bucket lock. Make mptcp_token_accept() and mptcp_token_destroy_request() re-check token_node under the same lock and treat an already moved or removed request as a normal race instead of warning. If the passive MP_CAPABLE socket cannot claim the token, fail mptcp_sk_clone_init() and let the subflow fall back instead of installing a socket with mismatched token ownership. Keep token publication after the cloned msk has its first subflow and connection list initialized. If token accept still fails, tear the cloned MPTCP socket down by open-coding the inet-level forced-close preparation, avoiding TCP-only helpers such as tcp_done() or inet_csk_prepare_forced_close() on the MPTCP master socket. Fixes: c905dee62232 ("tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitt= ing SYN+ACKs.") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: Codex:gpt-5.4 Reported-by: Sashiko Closes: https://sashiko.dev/#/patchset/86e2514b533bf4d55d4aa2fdbf1404022e8c= 9430.1776149210.git.caoruide123%40gmail.com Signed-off-by: Ruide Cao Signed-off-by: Ren Wei --- net/mptcp/protocol.c | 31 +++++++++++++++++---- net/mptcp/protocol.h | 4 ++- net/mptcp/subflow.c | 2 ++ net/mptcp/token.c | 61 +++++++++++++++++++++++++++++++++++++----- net/mptcp/token_test.c | 4 +-- 5 files changed, 87 insertions(+), 15 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 7c8180d8d5ef..b05c8d37a083 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3561,6 +3561,24 @@ static void mptcp_copy_ip_options(struct sock *newsk= , const struct sock *sk) rcu_read_unlock(); } =20 +static void mptcp_sk_clone_destroy(struct sock *nsk) +{ + struct mptcp_sock *msk =3D mptcp_sk(nsk); + + mptcp_release_sched(msk); + mptcp_set_state(nsk, TCP_CLOSE); + /* inet_csk_prepare_forced_close() clears TCP sock_ops state via + * tcp_sk(), but nsk is an MPTCP master socket; keep the inet-level + * destroy preparation here. + */ + bh_unlock_sock(nsk); + sock_put(nsk); + sock_set_flag(nsk, SOCK_DEAD); + tcp_orphan_count_inc(); + inet_sk(nsk)->inet_num =3D 0; + inet_csk_destroy_sock(nsk); +} + struct sock *mptcp_sk_clone_init(const struct sock *sk, const struct mptcp_options_received *mp_opt, struct sock *ssk, @@ -3620,11 +3638,6 @@ struct sock *mptcp_sk_clone_init(const struct sock *= sk, list_add(&subflow->node, &msk->conn_list); sock_hold(ssk); =20 - /* new mpc subflow takes ownership of the newly - * created mptcp socket - */ - mptcp_token_accept(subflow_req, msk); - /* set msk addresses early to ensure mptcp_pm_get_local_id() * uses the correct data */ @@ -3633,6 +3646,14 @@ struct sock *mptcp_sk_clone_init(const struct sock *= sk, mptcp_rcv_space_init(msk, ssk); msk->rcvq_space.time =3D mptcp_stamp(); =20 + if (!mptcp_token_accept(subflow_req, msk)) { + list_del_init(&subflow->node); + WRITE_ONCE(msk->first, NULL); + sock_put(ssk); + mptcp_sk_clone_destroy(nsk); + return NULL; + } + if (mp_opt->suboptions & OPTION_MPTCP_MPC_ACK) __mptcp_subflow_fully_established(msk, subflow, mp_opt); bh_unlock_sock(nsk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 1b80f2d6ec5a..69d531c770c4 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1076,9 +1076,11 @@ static inline void mptcp_token_init_request(struct r= equest_sock *req) } =20 int mptcp_token_new_request(struct request_sock *req); +void mptcp_token_move_request(struct request_sock *req, + struct request_sock *new_req); void mptcp_token_destroy_request(struct request_sock *req); int mptcp_token_new_connect(struct sock *ssk); -void mptcp_token_accept(struct mptcp_subflow_request_sock *r, +bool mptcp_token_accept(struct mptcp_subflow_request_sock *r, struct mptcp_sock *msk); bool mptcp_token_exists(u32 token); struct mptcp_sock *mptcp_token_get_sock(struct net *net, u32 token); diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 8f8e1229766d..d40ab09ab75b 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -56,6 +56,8 @@ void mptcp_subflow_reqsk_clone(struct request_sock *req, =20 if (subflow_req->msk) sock_hold((struct sock *)subflow_req->msk); + + mptcp_token_move_request(req, new_req); } =20 static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonc= e2, diff --git a/net/mptcp/token.c b/net/mptcp/token.c index f1a50f367add..24877a2c3772 100644 --- a/net/mptcp/token.c +++ b/net/mptcp/token.c @@ -180,6 +180,36 @@ int mptcp_token_new_connect(struct sock *ssk) return 0; } =20 +void mptcp_token_move_request(struct request_sock *req, + struct request_sock *new_req) +{ + struct mptcp_subflow_request_sock *subflow_req =3D mptcp_subflow_rsk(req); + struct mptcp_subflow_request_sock *new_subflow_req; + struct mptcp_subflow_request_sock *pos; + struct token_bucket *bucket; + + new_subflow_req =3D mptcp_subflow_rsk(new_req); + + if (hlist_nulls_unhashed_lockless(&subflow_req->token_node)) { + mptcp_token_init_request(new_req); + return; + } + + bucket =3D token_bucket(subflow_req->token); + spin_lock_bh(&bucket->lock); + if (hlist_nulls_unhashed(&subflow_req->token_node)) { + mptcp_token_init_request(new_req); + } else { + pos =3D __token_lookup_req(bucket, subflow_req->token); + if (pos =3D=3D subflow_req) + hlist_nulls_replace_init_rcu(&subflow_req->token_node, + &new_subflow_req->token_node); + else + mptcp_token_init_request(new_req); + } + spin_unlock_bh(&bucket->lock); +} + /** * mptcp_token_accept - replace a req sk with full sock in token hash * @req: the request socket to be removed @@ -187,24 +217,36 @@ int mptcp_token_new_connect(struct sock *ssk) * * Called when a SYN packet creates a new logical connection, i.e. * is not a join request. + * + * Return: true on success. */ -void mptcp_token_accept(struct mptcp_subflow_request_sock *req, +bool mptcp_token_accept(struct mptcp_subflow_request_sock *req, struct mptcp_sock *msk) { struct mptcp_subflow_request_sock *pos; struct sock *sk =3D (struct sock *)msk; struct token_bucket *bucket; + bool ret =3D false; =20 - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); bucket =3D token_bucket(req->token); spin_lock_bh(&bucket->lock); + if (hlist_nulls_unhashed(&req->token_node)) + goto unlock; =20 - /* pedantic lookup check for the moved token */ pos =3D __token_lookup_req(bucket, req->token); - if (!WARN_ON_ONCE(pos !=3D req)) - hlist_nulls_del_init_rcu(&req->token_node); + if (pos !=3D req) + goto unlock; + + hlist_nulls_del_init_rcu(&req->token_node); __sk_nulls_add_node_rcu((struct sock *)msk, &bucket->msk_chain); + ret =3D true; + +unlock: spin_unlock_bh(&bucket->lock); + if (ret) + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + + return ret; } =20 bool mptcp_token_exists(u32 token) @@ -355,16 +397,21 @@ void mptcp_token_destroy_request(struct request_sock = *req) struct mptcp_subflow_request_sock *pos; struct token_bucket *bucket; =20 - if (hlist_nulls_unhashed(&subflow_req->token_node)) + if (hlist_nulls_unhashed_lockless(&subflow_req->token_node)) return; =20 bucket =3D token_bucket(subflow_req->token); spin_lock_bh(&bucket->lock); + if (hlist_nulls_unhashed(&subflow_req->token_node)) + goto unlock; + pos =3D __token_lookup_req(bucket, subflow_req->token); - if (!WARN_ON_ONCE(pos !=3D subflow_req)) { + if (pos =3D=3D subflow_req) { hlist_nulls_del_init_rcu(&pos->token_node); bucket->chain_len--; } + +unlock: spin_unlock_bh(&bucket->lock); } =20 diff --git a/net/mptcp/token_test.c b/net/mptcp/token_test.c index 4fc39fa2e262..be9acce8a567 100644 --- a/net/mptcp/token_test.c +++ b/net/mptcp/token_test.c @@ -99,7 +99,7 @@ static void mptcp_token_test_accept(struct kunit *test) KUNIT_ASSERT_EQ(test, 0, mptcp_token_new_request((struct request_sock *)req)); msk->token =3D req->token; - mptcp_token_accept(req, msk); + KUNIT_EXPECT_TRUE(test, mptcp_token_accept(req, msk)); KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, msk->token= )); =20 /* this is now a no-op */ @@ -122,7 +122,7 @@ static void mptcp_token_test_destroyed(struct kunit *te= st) KUNIT_ASSERT_EQ(test, 0, mptcp_token_new_request((struct request_sock *)req)); msk->token =3D req->token; - mptcp_token_accept(req, msk); + KUNIT_EXPECT_TRUE(test, mptcp_token_accept(req, msk)); =20 /* simulate race on removal */ refcount_set(&sk->sk_refcnt, 0); --=20 2.43.0