From: Yilin Zhang <yilinzhang@moonshot.ai>
tcp_fastopen_create_child() hands the SYN packet itself to
subflow_syn_recv_sock(). For an MP_JOIN request this takes the
fatal fallback: the cloned child is destroyed and handed back with
drop_req flagged, but tcp_fastopen_create_child() does not check
the flag and queues it, so accept() can expose the freed child.
MP_JOIN cannot use Fast Open: data on a subflow requires the
completed HMAC exchange (RFC 8684, sec. 3.2). Refuse it (only the
TFO path passes a SYN skb here) and let tcp_conn_request() fall
back to the regular MP_JOIN handshake; also strip the Fast Open
cookie from MP_JOIN SYN/ACKs.
Fixes: 90bf45134d55 ("mptcp: add new sock flag to deal with join subflows")
Cc: stable@vger.kernel.org
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Suggested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
[ Moving code to avoid clearing TS and consolidating checks. ]
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Note: I'm taking over this series because the v3 got lost a bit, the v4
only contains minor modifications, no need to delay this fix any
longer.
v4:
- Disable TFO without clearing tstamp_ok.
- Moving SYN check inside the existing MPJ section.
- Check for SYN only. (Paolo)
v3:
- https://lore.kernel.org/20260920061904.3575780-1-yilinzhang@moonshot.ai
v2:
- https://lore.kernel.org/20260903094010.4066892-1-yilinzhang@moonshot.ai
v1:
- https://lore.kernel.org/20260902121247.3248539-1-yilinzhang@moonshot.ai
---
net/mptcp/subflow.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 78e886b20258..00677fb3efcd 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -379,6 +379,10 @@ static void subflow_prep_synack(const struct sock *sk, struct request_sock *req,
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
struct inet_request_sock *ireq = inet_rsk(req);
+ /* MP_JOIN cannot use TFO, do not send a cookie in the SYN/ACK */
+ if (foc && mptcp_subflow_rsk(req)->mp_join)
+ foc->len = -1;
+
/* clear tstamp_ok, as needed depending on cookie */
if (foc && foc->len > -1)
ireq->tstamp_ok = 0;
@@ -887,6 +891,13 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
fallback = true;
} else if (subflow_req->mp_join) {
+ /* a SYN skb here comes from TFO, which MP_JOIN cannot use: just
+ * fall back to the regular path.
+ */
+ if ((TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_ACK)) ==
+ TCPHDR_SYN)
+ return NULL;
+
mptcp_get_options(skb, &mp_opt);
if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK))
fallback = true;
---
base-commit: d8a4f4c59da52b7c31ae337243b8473a19a3f819
change-id: 20261030-mptcp-tfo-mpj-55fedc3189fc
Best regards,
--
Matthieu Baerts (NGI0) <matttbe@kernel.org>
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Fri, 30 Oct 2026 23:03:51 +0100 you wrote:
> From: Yilin Zhang <yilinzhang@moonshot.ai>
>
> tcp_fastopen_create_child() hands the SYN packet itself to
> subflow_syn_recv_sock(). For an MP_JOIN request this takes the
> fatal fallback: the cloned child is destroyed and handed back with
> drop_req flagged, but tcp_fastopen_create_child() does not check
> the flag and queues it, so accept() can expose the freed child.
>
> [...]
Here is the summary with links:
- [net,v4] mptcp: do not use Fast Open on MP_JOIN subflows
https://git.kernel.org/netdev/net/c/6d2cf411aba2
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
Hi Yilin,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Unstable: 3 failed test(s): bpftest_test_progs-cpuv4_mptcp bpftest_test_progs-no_alu32_mptcp bpftest_test_progs_mptcp ⚠️
- KVM Validation: btf-debug (only bpftest_all): Unstable: 3 failed test(s): bpftest_test_progs-cpuv4_mptcp bpftest_test_progs-no_alu32_mptcp bpftest_test_progs_mptcp ⚠️
- Perf: Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/41138587801
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/a00b9355ed10
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1197522
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
Hi! This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information: - Whether the issue was actually triggered, or is only theoretical (e.g. found by code inspection). If it was triggered please include the symptoms, like the stack trace or error messages. Please do not repost the series just to address the above. Instead, reply to this email with the missing information, so that reviewers can take it into account. If the series needs another revision for other reasons, please include the information in the commit messages then. The evaluation is done by an LLM so it may be wrong, if you think that is the case please reply and explain.
On 30/10/2026 23:08, netdev-bot+sinfo@kernel.org wrote: > Hi! > > This is an automated message. This series looks like a fix, but its > commit messages seem to be missing some information: > > - Whether the issue was actually triggered, or is only theoretical > (e.g. found by code inspection). If it was triggered please include > the symptoms, like the stack trace or error messages. Indeed, I forgot to add: the same reproducer from v1 still applies: the issue was actually triggered. The symptoms are described in the commit message. Cheers, Matt -- Sponsored by the NGI0 Core fund.
© 2016 - 2026 Red Hat, Inc.