From nobody Sat Aug 15 20:30:37 2026 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) (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 5C455449EA9 for ; Thu, 6 Aug 2026 11:14:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786014894; cv=none; b=G+VD38MXppNyClz+LUkG/QoTWd56deNDQihLQ5cLwGduJqsJ8V8np/4B3/vNcLf8l6QH8ua3Sq5a3p1GmNN/zLTHEGnjse8i8TDkMZG+z63QvgSou+MKV17jZNOmlfbJnCAP9IU2B6zfY4q7n1jN7Sx1Q9D47kC2UjFhJ240zwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786014894; c=relaxed/simple; bh=WmK8KZTr19xuBbBZECD6AVvHrr5CmfBlYQve7lOMDsw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XY+xFcZ6YfW7vSmmSmALdKHD0fXHWaWaBmQifMwxXOL91L3C8JPiGirY0QCVgbDVnJGG73LEKdxcvN7xEDRFCYL6/jFOjOO6AoNiAKPv8PLXyMlk280VKztzn/0QK29zMv+uqJppvhfnbpGankIy3WHwKN0GrkJ+B4SOkch/Q4E= 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=Z2qEoBFL; arc=none smtp.client-ip=209.85.210.169 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="Z2qEoBFL" Received: by mail-pf1-f169.google.com with SMTP id d2e1a72fcca58-8487214ad2bso3168957b3a.1 for ; Thu, 06 Aug 2026 04:14:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1786014893; x=1786619693; 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=29AyUjE5Vfxw6W9VRHm3bjock3hYe1PRYtirYyF9Kc0=; b=Z2qEoBFLNQemBM3ppvh4IZ17/jMl3qhaWOA7hESe5Gf0PiNXCAMDjN3Z+fZMKlEb85 fdjmqxrMHzPs2HOelT0tot+qquBidc+xbNBOwzwtSfX+EEev01yGtJZW/xOPQuOCJ5b2 jfgN8oOvMWsJuCdC6C2wE/03GmAamgcD7Za1EiGvl/1bLgV9lwBRK/gVg/OypijSUNoy wLMi+dcZssLkjgx1EQ8cw+uNKB53JyeDxzDs6iyF/GnSEqF0j/wwPpWcn+e6/cn4JU/Q tYxmUOm0Co7IAm/3/HPXpzMP+yL8pcT6gFS7sUQL7UiXZ/Y0HctHR2x/0VgDtY+BMeUL UfAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786014893; x=1786619693; 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=29AyUjE5Vfxw6W9VRHm3bjock3hYe1PRYtirYyF9Kc0=; b=HzqCpAr6sie7JvROqYU6oMI5gn6CUvtX1Fy4lkwBmUlY2+OyW4Q7la3QIapPyAYbSn CM7Fhd8jSdfqqdNHzo/19ilyckXxOowL4+DNNCzSJ6MBE7HFn0l6keH1iAWD6dVElwv3 JYxAyv9orG3YfV7qzO/UwVSddNTXaAuoTpWY98U4fFrIY8/o4v8DRa6ZSm7O3TK1DYya v43epXYSJqdlU32XFLb35gR7hPjlkfv3U5H2ysJfgnjb3AwuJRxoG8QDfvSLCVhQn4es wCuw7G47+bu+IK9993FeKRiIdYguRO6Z9KLbaraGpwwRmss06aQXj4yRUjuYH5LUWBVI tVsA== X-Forwarded-Encrypted: i=1; AHgh+RpynI1k0iJi8BoI9KanCO/zvVrKF8YkrdcHpxfeuh1hvPJH8inYTjGqlKf9rkf2DJS0bzBnWQ==@lists.linux.dev X-Gm-Message-State: AOJu0YyYLi0bgdPpQd1NYZq+tBPV9KH9wz65JDPmne4SyhQwq9R41t8Z X4rVl8vKad2IlDdgtjGWkUdR3EPcJBJV2/GazYyLh8CiJfz+IlkGTq8CoNFuKV2InayP X-Gm-Gg: AR+sD11w4jd8QE21Vw673PeUVyt9cW0GUowrrECR8iITO5W2NJGnEL8ttkvSOmYL6fi n7hn3OcIq5Gl1AMaatF6nnojytnyj9O6DGm8oxyEtZO7/yuQrNcETyHjmfFCmzHUNURkS1iVbdg wHlMX15b1qKvsZ8Vc1LIqlWaSD+TO9tnKPC+3U1Kh5URgFYHrecNQ0lRqakw5hL14wCI009B/R8 jvQwmeMbmhAt/bWFeLCjRUS1R3TTdGet3u/JnxrkVfBv+/Sy+0FD8r2sxdO0RWc7QUHvA6Qzd0V 4RvgXKaD2ttJ0C7B2UBvti5RlYfci+B4dIIvFWJsLXOvXGzQeRxfV94REt+DfAoJD4IejnsAkcl lUB1IA5CM6FYwq3bxifLLfeMuG7jeA84knk5cIhs7Amdc80oXhPQUO4zorQYRulxq7M2hn7cncu SJKFyCzt1u31eii5ze7Cdi03UhhIKjdVX3CMKlvsW75tfpBz00F6E7B2I= X-Received: by 2002:aa7:9303:0:b0:845:cf86:9469 with SMTP id d2e1a72fcca58-84f2e004570mr17499947b3a.29.1786014892652; Thu, 06 Aug 2026 04:14:52 -0700 (PDT) Received: from enjou-Legion-Y7000P-2019 ([165.232.167.5]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84f453b07cdsm1214705b3a.17.2026.08.06.04.14.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 04:14:52 -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, daniel@iogearbox.net, kafai@fb.com, kylebot@openai.com, david.lee@trailofbits.com, vega@nebusec.ai, caoruide123@gmail.com, weir@nebusec.ai, sashiko-bot@kernel.org Subject: [PATCH net v3 1/2] mptcp: hold MP_JOIN msk ref when cloning reqsk Date: Thu, 6 Aug 2026 19:14:30 +0800 Message-ID: <74e00d4f4fedec635ef06a16b1bf28a281b9e7e5.1785995291.git.caoruide123@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_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 8e386899ceb9..be7260821566 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:37 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (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 132AC430CC1 for ; Thu, 6 Aug 2026 11:15:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786014905; cv=none; b=OT8jmQnAd9QMqw/abgKubMS1N0lXh3DFIyodgQwJ1zuGcRmCa0WZ1tGhCXZpnISeOWAMPJsXZo5ROP2qj/Pv4IxWJ1MhmmRTZ/M4gGjv7ItWVN8v30BoSk1wnD69sS9PJC7sV7zQAQ8OL4r3YJ0rBGcmJfbQNA+OxPiQbN+FR6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786014905; c=relaxed/simple; bh=amyEg9s1SM6GN6svOrv3HLp1ySuyy+gLUZT+5HjBiDw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EPoYxX1zwx3YNcsGthDzYGNjzboWeOdizaY79YZFo1MPx4iKlVjeI7M4wqsQFzMIxdMQWxt6gf0iHfbBSAQjZlTsskQwU50sM3KSTN///sC5KAdOnoYtRZmd4PtWW2aJNmjHsqiCBZQeaDZkSDfN1xSLVJifs5uxtxqX3z7UcOg= 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=SizSIQE6; arc=none smtp.client-ip=209.85.215.175 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="SizSIQE6" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-cbb7926836eso1530639a12.3 for ; Thu, 06 Aug 2026 04:15:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1786014903; x=1786619703; 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=5SvYcx4ai7A+LAhsWyrU62LuZiiW2rO6oOfRGjc++k4=; b=SizSIQE6JtQOfoIZzkHc051AGhWG37W693eoEN69YVHUPdd9x1LWWlvYPUtWcKQoGP yBBMCLFfVRjFDcJpNHtmlIFpF3fkdukv3lCxyFcH9VyHNHkWL1tDNxD94gAonjeO+AjK bOtyyeKDIDpgTdhx9x5he1lJsLv02qMZc3HK3sCKGNRFjTPiZ+GvVzxRVBh0YDh5C3XV z3EVqW+vaXQ0XzyZuW45xOzQ3lyzFPSVbhnL7qAHiAWOcUjb3BxDbkbeEYDLcp7y25CF U/X0Abxc+CrV4Ov/H0abm74rBRVz9aXh8fRIzfKNW5u8lVd9AElBBqE1W4BQeYY0qHBS 6nOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786014903; x=1786619703; 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=5SvYcx4ai7A+LAhsWyrU62LuZiiW2rO6oOfRGjc++k4=; b=qoQTl3zl12q9Hj0wUm4EVP66Gd1tHiwn+WzvU/eAWb2eJAck7vH91IqC9Pidh23lMk Naoft2gITclTrHhc76Hyz/wWXQVqCX6SIWIbSP2hWMsmaUNtaJr2kozSt704r+vRmZVt OZuSwdCyulJ0pTeyHesnPWb/RcbXVgpdB7TLLk/zkE5+BKUfJaI3zr8YvhWfp5h0pWhB ZFVrLn7KktesLFIeqW0SrvMplTapLfWuxckVSgdmhIU86TjuCiM5m65VuiF7GuLnaXAH gKIcEe4YLBWRi1BIBUc1/PnpPdqXFpO3Uk+ts94WXkcXYveEmKA6SOtgLMoYD6vX5MiF Mv9g== X-Forwarded-Encrypted: i=1; AHgh+Rrtq9/7gvuN6JW6pCnh3SImNRmMV2PA95jpICUydX+L5W3QdXdM7PRSK/vPyUyin0qmAkBsLg==@lists.linux.dev X-Gm-Message-State: AOJu0Yz5bNFuOJW7XyukVVmHR51FQ3PNYCSLKzU9xXSYaA0WkTfB2ph2 7yCYp9RmFERjww5Sgt3HwDoQwGusw4WdCn2lPxKID8TAr/2z3eIGRJkSAp4GXw+ow8/B X-Gm-Gg: AR+sD10h0sh/iIHVJTMDaLoJCn4Z+9/OEsAaigOxnGyty9/z2gs0vyQdv14M5N7xjmA gYjVhNL5KNNTCmgLQ3R8YFB2N9/nYQQiE1nWQSJqwrYFTF3f3R003mr9n3LfhwStzM60uXK/v3S jMuuKI7jQn1G8LMxqqB1/9pimHLwT68rgYYDSMKJRRNaaa2sHXBQyMQNViesaMt71oPzolmCy4B aZJ7mtfzyh6haOqVuo5S4zOh3Y/jVS2zxBb81e9Yy4f6Vwl6C/21fffdVM0g2YQsIGnodg2wcpe 5yntoVuOWaL8d/YhY7XXz7kOf4UjeeIS1G0S9AFeO2RVYjsUvbU16C8Wocz+YNZhy3ykGmMelam IxWsiJZNjlKRzCJ4Clv0beiMucvPiL3LZZKroVuNxn+vmhJhE8L8lAOaTQ8Wh2Jd7psC7MCCjoS Pli6K1OORBtEaLXa3bMP25HNWJmHRtvuLuwWM2eLL1UzNCiKoWUJW5DCfZGJARh0w4VGkMnvWFC 8jDgg== X-Received: by 2002:a05:6a00:2d8d:b0:846:bc81:3e29 with SMTP id d2e1a72fcca58-84f2e0228aemr14866416b3a.2.1786014903269; Thu, 06 Aug 2026 04:15:03 -0700 (PDT) Received: from enjou-Legion-Y7000P-2019 ([165.232.167.5]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84f453b07cdsm1214705b3a.17.2026.08.06.04.14.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 04:15:02 -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, daniel@iogearbox.net, kafai@fb.com, kylebot@openai.com, david.lee@trailofbits.com, vega@nebusec.ai, caoruide123@gmail.com, weir@nebusec.ai, sashiko-bot@kernel.org Subject: [PATCH net v3 2/2] mptcp: fix MP_CAPABLE token migration when cloning reqsk Date: Thu, 6 Aug 2026 19:14:31 +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_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. 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 | 12 +++++---- net/mptcp/protocol.h | 4 ++- net/mptcp/subflow.c | 2 ++ net/mptcp/token.c | 61 +++++++++++++++++++++++++++++++++++++----- net/mptcp/token_test.c | 4 +-- 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index ca644ec53eed..07eaa6858d05 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3608,17 +3608,19 @@ struct sock *mptcp_sk_clone_init(const struct sock = *sk, */ mptcp_set_state(nsk, TCP_ESTABLISHED); =20 + if (!mptcp_token_accept(subflow_req, msk)) { + mptcp_release_sched(msk); + inet_csk_prepare_forced_close(nsk); + tcp_done(nsk); + return NULL; + } + /* The msk maintain a ref to each subflow in the connections list */ WRITE_ONCE(msk->first, ssk); subflow =3D mptcp_subflow_ctx(ssk); 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 */ diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 4a2d40cd7b13..c58cfb1326b7 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1074,9 +1074,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 be7260821566..65d876a08233 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