Skip to contentSkip to conversation

mptcp: fix recent failed backports (20260919)

PATCH Applied Matthieu Baerts (NGI0) 3 participants 14 messages Sep 19 – Sep 20

Subsystems (3)
lore
Share & tools
lore

Matthieu Baerts (NGI0)

author maintainer
#0 lore raw

cover mptcp: fix recent failed backports (20260919)

The following patches could not be applied without conflicts in this tree:

- 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset")
- 42064de57fb8 ("mptcp: close race between scheduler and state change")
- f3ef03357396 ("mptcp: fix bad accounting in __mptcp_subflow_push_pending()")

I backported the following commits to avoid conflicts:

- 581c8cbfa934 ("mptcp: annotate data-races around subflow->fully_established")
- caa4a79f74f3 ("mptcp: remove unneeded READ_ONCE() annotation")

Conflicts (if any) have been resolved, and documented in each patch.

Gang Yan (1):
mptcp: annotate data-races around subflow->fully_established

Paolo Abeni (4):
mptcp: remove unneeded READ_ONCE() annotation
mptcp: avoid unneeded actions on subflow reset
mptcp: close race between scheduler and state change
mptcp: fix bad accounting in __mptcp_subflow_push_pending()

 net/mptcp/protocol.c | 13 ++++++++-----
 net/mptcp/protocol.h |  1 +
 net/mptcp/subflow.c  | 11 +++++++++++
 3 files changed, 20 insertions(+), 5 deletions(-)
Signature · 1 line
2.55.0
author maintainer
#1 lore raw

PATCH 1/5 mptcp: annotate data-races around subflow->fully_established

From: Gang Yan <[email protected]>

commit 581c8cbfa934aaa555daa4e843242fcecc160f05 upstream.

We introduce the same handling for potential data races with the 'fully_established' flag in subflow as previously done for msk->fully_established.

Additionally, we make a crucial change: convert the subflow's 'fully_established' from 'bit_field' to 'bool' type. This is necessary because methods for avoiding data races don't work well with 'bit_field'. Specifically, the 'READ_ONCE' needs to know the size of the variable being accessed, which is not supported in 'bit_field'. Also, 'test_bit' expect the address of 'bit_field'.

Stable-dep-of: 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset")

---
 net/mptcp/options.c  | 4 ++--
 net/mptcp/protocol.c | 2 +-
 net/mptcp/protocol.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)
net/mptcp/options.c +2 -2
index d238dd374ce9..123c3691833f 100644
@@ -532,7 +532,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 		return false;
 
 	/* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */
-	if (subflow->fully_established || snd_data_fin_enable ||
+	if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable ||
 	    subflow->snd_isn != TCP_SKB_CB(skb)->seq ||
 	    sk->sk_state != TCP_ESTABLISHED)
 		return false;
@@ -999,7 +999,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
 	/* here we can process OoO, in-window pkts, only in-sequence 4th ack
 	 * will make the subflow fully established
 	 */
-	if (likely(subflow->fully_established)) {
+	if (likely(READ_ONCE(subflow->fully_established))) {
 		/* on passive sockets, check for 3rd ack retransmission
 		 * note that msk is always set by subflow_syn_recv_sock()
 		 * for mp_join subflows
net/mptcp/protocol.c +1 -1
index 2f34e92d9cce..a4054ed24605 100644
@@ -3685,7 +3685,7 @@ static void schedule_3rdack_retransmission(struct sock *ssk)
 	struct tcp_sock *tp = tcp_sk(ssk);
 	unsigned long timeout;
 
-	if (mptcp_subflow_ctx(ssk)->fully_established)
+	if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established))
 		return;
 
 	/* reschedule with a timeout above RTT, as we must look only for drop */
net/mptcp/protocol.h +1 -1
index 2ac28f6ddff5..cd4481c93b6d 100644
@@ -545,7 +545,7 @@ struct mptcp_subflow_context {
 		is_mptfo : 1,	    /* subflow is doing TFO */
 		close_event_done : 1,       /* has done the post-closed part */
 		mpc_drop : 1,	    /* the MPC option has been dropped in a rtx */
-		__unused : 8;
+		__unused : 9;
 	bool	data_avail;
 	bool	scheduled;
 	bool	pm_listener;	    /* a listener managed by the kernel PM? */
Signature · 1 line
2.55.0
maintainer Applied
#2 lore raw

Patch "mptcp: annotate data-races around subflow->fully_established" has been added to the 6.12-stable tree

This is a note to let you know that I've just added the patch titled

    mptcp: annotate data-races around subflow->fully_established

to the 6.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-annotate-data-races-around-subflow-fully_established.patch
and it can be found in the queue-6.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Sat Sep 19 21:57:10 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Sat, 19 Sep 2026 21:56:44 +0200
Subject: mptcp: annotate data-races around subflow->fully_established
To: [email protected], [email protected], [email protected]
Cc: Gang Yan <[email protected]>, [email protected], "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: Gang Yan <[email protected]>

commit 581c8cbfa934aaa555daa4e843242fcecc160f05 upstream.

We introduce the same handling for potential data races with the 'fully_established' flag in subflow as previously done for msk->fully_established.

Additionally, we make a crucial change: convert the subflow's 'fully_established' from 'bit_field' to 'bool' type. This is necessary because methods for avoiding data races don't work well with 'bit_field'. Specifically, the 'READ_ONCE' needs to know the size of the variable being accessed, which is not supported in 'bit_field'. Also, 'test_bit' expect the address of 'bit_field'.

Stable-dep-of: 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset")

---
 net/mptcp/options.c  |    4 ++--
 net/mptcp/protocol.c |    2 +-
 net/mptcp/protocol.h |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)
net/mptcp/options.c +2 -2
@@ -532,7 +532,7 @@ static bool mptcp_established_options_mp
 		return false;
 
 	/* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */
-	if (subflow->fully_established || snd_data_fin_enable ||
+	if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable ||
 	    subflow->snd_isn != TCP_SKB_CB(skb)->seq ||
 	    sk->sk_state != TCP_ESTABLISHED)
 		return false;
@@ -999,7 +999,7 @@ static bool check_fully_established(stru
 	/* here we can process OoO, in-window pkts, only in-sequence 4th ack
 	 * will make the subflow fully established
 	 */
-	if (likely(subflow->fully_established)) {
+	if (likely(READ_ONCE(subflow->fully_established))) {
 		/* on passive sockets, check for 3rd ack retransmission
 		 * note that msk is always set by subflow_syn_recv_sock()
 		 * for mp_join subflows
net/mptcp/protocol.c +1 -1
@@ -3685,7 +3685,7 @@ static void schedule_3rdack_retransmissi
 	struct tcp_sock *tp = tcp_sk(ssk);
 	unsigned long timeout;
 
-	if (mptcp_subflow_ctx(ssk)->fully_established)
+	if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established))
 		return;
 
 	/* reschedule with a timeout above RTT, as we must look only for drop */
net/mptcp/protocol.h +1 -1
@@ -545,7 +545,7 @@ struct mptcp_subflow_context {
 		is_mptfo : 1,	    /* subflow is doing TFO */
 		close_event_done : 1,       /* has done the post-closed part */
 		mpc_drop : 1,	    /* the MPC option has been dropped in a rtx */
-		__unused : 8;
+		__unused : 9;
 	bool	data_avail;
 	bool	scheduled;
 	bool	pm_listener;	    /* a listener managed by the kernel PM? */

Patches currently in stable-queue which might be from [email protected] are

queue-6.12/mptcp-annotate-data-races-around-subflow-fully_established.patch queue-6.12/selftests-mptcp-fix-an-uaf-in-mptcp_connect.c.patch queue-6.12/mptcp-fix-bad-accounting-in-__mptcp_subflow_push_pending.patch queue-6.12/mptcp-syncookies-remember-the-request-backup-flag.patch queue-6.12/mptcp-remove-unneeded-read_once-annotation.patch queue-6.12/mptcp-close-race-between-scheduler-and-state-change.patch queue-6.12/tcp-use-gfp_atomic-in-tcp_send_active_reset.patch queue-6.12/mptcp-avoid-unneeded-actions-on-subflow-reset.patch queue-6.12/mptcp-options-handle-mpc-data-csum-reqd-no-csum.patch queue-6.12/mptcp-subflow-no-need-to-copy-thmac-during-ulp_clone.patch

#3 lore raw

Re: Patch "mptcp: annotate data-races around subflow->fully_established" has been added to the 6.12-stable tree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Low] mptcp: build failure due to READ_ONCE() on bit-field --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] mptcp: build failure due to READ_ONCE() on bit-field
--

commit 2cede4d0675228e6db5b209f56d2a298cf7cb2e9
Author: [email protected] <[email protected]>
Subject: Patch "mptcp: annotate data-races around subflow->fully_established" has been added to the 6.12-stable tree

This commit annotates data races around the fully_established flag in the mptcp subflow context. It aims to convert the flag from a bit-field to a boolean type to safely use READ_ONCE() and WRITE_ONCE().

Quoted 6 lines

Additionally, we make a crucial change: convert the subflow's 'fully_established' from 'bit_field' to 'bool' type. This is necessary because methods for avoiding data races don't work well with 'bit_field'. Specifically, the 'READ_ONCE' needs to know the size of the variable being accessed, which is not supported in 'bit_field'. Also, 'test_bit' expect the address of 'bit_field'.

[Severity: Low]
Was the hunk converting this field to a boolean dropped during the backport? It appears fully_established is still defined as a bit-field in struct mptcp_subflow_context.

Additionally, the write side update was missed in the backport:

net/mptcp/subflow.c:__mptcp_subflow_fully_established() {
    ...
	subflow->fully_established = 1;
    ...
}

This lacks the WRITE_ONCE() annotation and continues to perform an unsafe read-modify-write on the shared bit-field word.

net/mptcp/options.c static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb, · line 464

Quoted 10 lines
net/mptcp/options.c +1 -1
index 370c3836b7712..1603b3702e220 100644
@@ -461,7 +461,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 		return false;
 
 	/* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */
-	if (subflow->fully_established || snd_data_fin_enable ||
+	if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable ||

[Severity: Low]
Does this trigger a compiler error? Since the struct modification was missed and fully_established remains a bit-field, applying READ_ONCE() here attempts to take the address of a bit-field, which is syntactically invalid in C.

[ ... ]

net/mptcp/protocol.h struct mptcp_subflow_context { · line 535

Quoted 10 lines
net/mptcp/protocol.h +1 -1
index 568a72702b080..e9dba0708ee70 100644
@@ -532,7 +532,7 @@ struct mptcp_subflow_context {
 		is_mptfo : 1,	    /* subflow is doing TFO */
 		close_event_done : 1,       /* has done the post-closed part */
 		mpc_drop : 1,	    /* the MPC option has been dropped in a rtx */
-		__unused : 8;
+		__unused : 9;

[Severity: Low]
Does this increase the total bit-field group to 33 bits, causing a boundary overflow?

Since fully_established wasn't actually removed from the bit-field group in this backport, incrementing the unused bits to 9 pushes the total beyond a 32-bit word size.

Quoted 3 lines
net/mptcp/protocol.h +0 -0
 	bool	data_avail;
 	bool	scheduled;
 	bool	pm_listener;	    /* a listener managed by the kernel PM? */
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/2026092037-islamic-default-0aca@gregkh?part=1
author maintainer
#4 lore raw

Re: Patch "mptcp: annotate data-races around subflow->fully_established" has been added to the 6.12-stable tree

Hello,

Quoted 2 lines · On 20/09/2026 09:48, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] mptcp: build failure due to READ_ONCE() on bit-field

Mmh, I missed the fact this commit has already been backported in commit 477aa7116a76 ("mptcp: annotate data-races around subflow ->fully_established"), but mostly reverted by caa4a79f74f3 ("mptcp:
remove unneeded READ_ONCE() annotation").

I don't know what's better here: either we leave it like that, and I can fix the size of the bit-field. Or we drop patch 1 and 2, and I resolve the small conflict on patch 3/5: commit 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset"). I can send a v2, and we can drop it if the other solution has been preferred.

Cheers,
Matt

Signature · 1 line
Sponsored by the NGI0 Core fund.
maintainer
#5 lore raw

Re: Patch "mptcp: annotate data-races around subflow->fully_established" has been added to the 6.12-stable tree

Quoted 11 lines · Matthieu Baerts

Hello,

Quoted 2 lines · On 20/09/2026 09:48, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] mptcp: build failure due to READ_ONCE() on bit-field

Mmh, I missed the fact this commit has already been backported in commit 477aa7116a76 ("mptcp: annotate data-races around subflow ->fully_established"), but mostly reverted by caa4a79f74f3 ("mptcp:
remove unneeded READ_ONCE() annotation").

Quoted 5 lines

I don't know what's better here: either we leave it like that, and I can fix the size of the bit-field. Or we drop patch 1 and 2, and I resolve the small conflict on patch 3/5: commit 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset"). I can send a v2, and we can drop it if the other solution has been preferred.

Your v2 looks good, thanks for that, I'll go replace the patches with those.

greg k-h

author maintainer
#6 lore raw

Re: Patch "mptcp: annotate data-races around subflow->fully_established" has been added to the 6.12-stable tree

Quoted 12 lines · Greg KH
Quoted 11 lines · Matthieu Baerts

Hello,

Quoted 2 lines · On 20/09/2026 09:48, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] mptcp: build failure due to READ_ONCE() on bit-field

Mmh, I missed the fact this commit has already been backported in commit 477aa7116a76 ("mptcp: annotate data-races around subflow ->fully_established"), but mostly reverted by caa4a79f74f3 ("mptcp:
remove unneeded READ_ONCE() annotation").

Quoted 8 lines
Quoted 5 lines

I don't know what's better here: either we leave it like that, and I can fix the size of the bit-field. Or we drop patch 1 and 2, and I resolve the small conflict on patch 3/5: commit 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset"). I can send a v2, and we can drop it if the other solution has been preferred.

Your v2 looks good, thanks for that, I'll go replace the patches with those.

Thank you! And sorry for the extra work :)

Cheers,
Matt

Signature · 1 line
Sponsored by the NGI0 Core fund.
author maintainer
#7 lore raw

PATCH 2/5 mptcp: remove unneeded READ_ONCE() annotation

In reply to Matthieu Baerts (NGI0)

From: Paolo Abeni <[email protected]>

commit caa4a79f74f32084ce28aee8653bc04df745970d upstream.

The subflow->fully_established flag is always written under the subflow socket lock. Reading such value under the same lock does not require any ONCE annotation.

Stable-dep-of: 2b0f561f21b2 ("mptcp: avoid unneeded actions on subflow reset")

---
 net/mptcp/options.c  | 4 ++--
 net/mptcp/protocol.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
net/mptcp/options.c +2 -2
index 123c3691833f..d238dd374ce9 100644
@@ -532,7 +532,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
 		return false;
 
 	/* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */
-	if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable ||
+	if (subflow->fully_established || snd_data_fin_enable ||
 	    subflow->snd_isn != TCP_SKB_CB(skb)->seq ||
 	    sk->sk_state != TCP_ESTABLISHED)
 		return false;
@@ -999,7 +999,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
 	/* here we can process OoO, in-window pkts, only in-sequence 4th ack
 	 * will make the subflow fully established
 	 */
-	if (likely(READ_ONCE(subflow->fully_established))) {
+	if (likely(subflow->fully_established)) {
 		/* on passive sockets, check for 3rd ack retransmission
 		 * note that msk is always set by subflow_syn_recv_sock()
 		 * for mp_join subflows
net/mptcp/protocol.c +1 -1
index a4054ed24605..2f34e92d9cce 100644
@@ -3685,7 +3685,7 @@ static void schedule_3rdack_retransmission(struct sock *ssk)
 	struct tcp_sock *tp = tcp_sk(ssk);
 	unsigned long timeout;
 
-	if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established))
+	if (mptcp_subflow_ctx(ssk)->fully_established)
 		return;
 
 	/* reschedule with a timeout above RTT, as we must look only for drop */
Signature · 1 line
2.55.0
author maintainer
#8 lore raw

PATCH 3/5 mptcp: avoid unneeded actions on subflow reset

In reply to Matthieu Baerts (NGI0)

From: Paolo Abeni <[email protected]>

commit 2b0f561f21b27c40c91ea4975268a06092bd7e9c upstream.

Once in a blue moon, the mptcp receive path can recursively call mptcp_data_ready() via state change under unlucky error conditions, and then try to hold the data lock again.

Break the recursion loop explicitly checking for the exceptional condition.

Add a new flag instead of using an existing one like 'closing', to exit early in subflow_state_change(), and explicitly flush the RX queue at reset time.

This avoids unneeded processing to check for available data -- calling get_mapping_status() and more on a dying subflow -- but also in error reporting and worker scheduling.

Note that we must consume the currently peeked skb before invoking mptcp_dss_corruption to avoid consuming it again after the eventual reset has freed it.

[ Note: conflict in protocol.c, because commit e0ca4057e0ec ("mptcp:
micro-optimize __mptcp_move_skb()") is not in this version, and is part of a consequent rx path refactor. The conflict is in the context, and is easy to resolve, "done = true" can be moved along without consequences. ]

---
 net/mptcp/protocol.c |  6 +++---
 net/mptcp/protocol.h |  3 ++-
 net/mptcp/subflow.c  | 11 +++++++++++
 3 files changed, 16 insertions(+), 4 deletions(-)
net/mptcp/protocol.c +3 -3
index 2f34e92d9cce..ff63ba5ee464 100644
@@ -747,13 +747,13 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
 				mptcp_dss_corruption(msk, ssk);
 			}
 		} else {
+			sk_eat_skb(ssk, skb);
+			done = true;
+
 			if (unlikely(!fin)) {
 				DEBUG_NET_WARN_ON_ONCE(1);
 				mptcp_dss_corruption(msk, ssk);
 			}
-
-			sk_eat_skb(ssk, skb);
-			done = true;
 		}
 
 		WRITE_ONCE(tp->copied_seq, seq);
net/mptcp/protocol.h +2 -1
index cd4481c93b6d..436d3c92ec4a 100644
@@ -545,7 +545,8 @@ struct mptcp_subflow_context {
 		is_mptfo : 1,	    /* subflow is doing TFO */
 		close_event_done : 1,       /* has done the post-closed part */
 		mpc_drop : 1,	    /* the MPC option has been dropped in a rtx */
-		__unused : 9;
+		resetting : 1,	    /* subflow is resetting */
+		__unused : 8;
 	bool	data_avail;
 	bool	scheduled;
 	bool	pm_listener;	    /* a listener managed by the kernel PM? */
net/mptcp/subflow.c +11 -0
index 267e0424eea5..cfa029b4d7f3 100644
@@ -440,6 +440,10 @@ void mptcp_subflow_reset(struct sock *ssk)
 	/* must hold: tcp_done() could drop last reference on parent */
 	sock_hold(sk);
 
+	subflow->resetting = 1;
+
+	/* No need to delay the actual close for to-be discarded data. */
+	__skb_queue_purge(&ssk->sk_receive_queue);
 	mptcp_send_active_reset_reason(ssk);
 	tcp_done(ssk);
 	if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags))
@@ -1857,6 +1861,13 @@ static void subflow_state_change(struct sock *sk)
 
 	__subflow_state_change(sk);
 
+	/* Rx queue processing is unneeded, error reporting will take place at
+	 * __mptcp_close_ssk() time and subflow reset can't happen in case of
+	 * fallback: subflow_sched_work_if_closed() would be a no-op.
+	 */
+	if (subflow->resetting)
+		return;
+
 	/* as recvmsg() does not acquire the subflow socket for ssk selection
 	 * a fin packet carrying a DSS can be unnoticed if we don't trigger
 	 * the data available machinery here.
Signature · 1 line
2.55.0
maintainer Applied
#9 lore raw

Patch "mptcp: avoid unneeded actions on subflow reset" has been added to the 6.12-stable tree

This is a note to let you know that I've just added the patch titled

mptcp: avoid unneeded actions on subflow reset

to the 6.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-avoid-unneeded-actions-on-subflow-reset.patch
and it can be found in the queue-6.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Sat Sep 19 21:57:17 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Sat, 19 Sep 2026 21:56:46 +0200
Subject: mptcp: avoid unneeded actions on subflow reset
To: [email protected], [email protected], [email protected]
Cc: Paolo Abeni <[email protected]>, [email protected], Xinyang Ge <[email protected]>, "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: Paolo Abeni <[email protected]>

commit 2b0f561f21b27c40c91ea4975268a06092bd7e9c upstream.

Once in a blue moon, the mptcp receive path can recursively call mptcp_data_ready() via state change under unlucky error conditions, and then try to hold the data lock again.

Break the recursion loop explicitly checking for the exceptional condition.

Add a new flag instead of using an existing one like 'closing', to exit early in subflow_state_change(), and explicitly flush the RX queue at reset time.

This avoids unneeded processing to check for available data -- calling get_mapping_status() and more on a dying subflow -- but also in error reporting and worker scheduling.

Note that we must consume the currently peeked skb before invoking mptcp_dss_corruption to avoid consuming it again after the eventual reset has freed it.

[ Note: conflict in protocol.c, because commit e0ca4057e0ec ("mptcp:
micro-optimize __mptcp_move_skb()") is not in this version, and is part of a consequent rx path refactor. The conflict is in the context, and is easy to resolve, "done = true" can be moved along without consequences. ]

---
 net/mptcp/protocol.c |    6 +++---
 net/mptcp/protocol.h |    3 ++-
 net/mptcp/subflow.c  |   11 +++++++++++
 3 files changed, 16 insertions(+), 4 deletions(-)
net/mptcp/protocol.c +3 -3
@@ -747,13 +747,13 @@ static bool __mptcp_move_skbs_from_subfl
 				mptcp_dss_corruption(msk, ssk);
 			}
 		} else {
+			sk_eat_skb(ssk, skb);
+			done = true;
+
 			if (unlikely(!fin)) {
 				DEBUG_NET_WARN_ON_ONCE(1);
 				mptcp_dss_corruption(msk, ssk);
 			}
-
-			sk_eat_skb(ssk, skb);
-			done = true;
 		}
 
 		WRITE_ONCE(tp->copied_seq, seq);
net/mptcp/protocol.h +2 -1
@@ -545,7 +545,8 @@ struct mptcp_subflow_context {
 		is_mptfo : 1,	    /* subflow is doing TFO */
 		close_event_done : 1,       /* has done the post-closed part */
 		mpc_drop : 1,	    /* the MPC option has been dropped in a rtx */
-		__unused : 9;
+		resetting : 1,	    /* subflow is resetting */
+		__unused : 8;
 	bool	data_avail;
 	bool	scheduled;
 	bool	pm_listener;	    /* a listener managed by the kernel PM? */
net/mptcp/subflow.c +11 -0
@@ -440,6 +440,10 @@ void mptcp_subflow_reset(struct sock *ss
 	/* must hold: tcp_done() could drop last reference on parent */
 	sock_hold(sk);
 
+	subflow->resetting = 1;
+
+	/* No need to delay the actual close for to-be discarded data. */
+	__skb_queue_purge(&ssk->sk_receive_queue);
 	mptcp_send_active_reset_reason(ssk);
 	tcp_done(ssk);
 	if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags))
@@ -1857,6 +1861,13 @@ static void subflow_state_change(struct
 
 	__subflow_state_change(sk);
 
+	/* Rx queue processing is unneeded, error reporting will take place at
+	 * __mptcp_close_ssk() time and subflow reset can't happen in case of
+	 * fallback: subflow_sched_work_if_closed() would be a no-op.
+	 */
+	if (subflow->resetting)
+		return;
+
 	/* as recvmsg() does not acquire the subflow socket for ssk selection
 	 * a fin packet carrying a DSS can be unnoticed if we don't trigger
 	 * the data available machinery here.

Patches currently in stable-queue which might be from [email protected] are

queue-6.12/mptcp-annotate-data-races-around-subflow-fully_established.patch queue-6.12/selftests-mptcp-fix-an-uaf-in-mptcp_connect.c.patch queue-6.12/mptcp-fix-bad-accounting-in-__mptcp_subflow_push_pending.patch queue-6.12/mptcp-syncookies-remember-the-request-backup-flag.patch queue-6.12/mptcp-remove-unneeded-read_once-annotation.patch queue-6.12/mptcp-close-race-between-scheduler-and-state-change.patch queue-6.12/tcp-use-gfp_atomic-in-tcp_send_active_reset.patch queue-6.12/mptcp-avoid-unneeded-actions-on-subflow-reset.patch queue-6.12/mptcp-options-handle-mpc-data-csum-reqd-no-csum.patch queue-6.12/mptcp-subflow-no-need-to-copy-thmac-during-ulp_clone.patch

author maintainer
#10 lore raw

PATCH 4/5 mptcp: close race between scheduler and state change

In reply to Matthieu Baerts (NGI0)

From: Paolo Abeni <[email protected]>

commit 42064de57fb83231fcc89663a94885f228a1ee53 upstream.

The mptcp scheduler may race with subflow sockets state change: data transmission on the selected socket may fail and a later release could try to use mss_now reset to 0 for a divide operation.

Address the issue by explicitly checking for the critical scenario.

---
 net/mptcp/protocol.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/mptcp/protocol.c +3 -1
index ff63ba5ee464..1304f3cb6d14 100644
@@ -1567,7 +1567,9 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk)
 
 static void mptcp_push_release(struct sock *ssk, struct mptcp_sendmsg_info *info)
 {
-	tcp_push(ssk, 0, info->mss_now, tcp_sk(ssk)->nonagle, info->size_goal);
+	if (info->mss_now)
+		tcp_push(ssk, 0, info->mss_now, tcp_sk(ssk)->nonagle,
+			 info->size_goal);
 	release_sock(ssk);
 }
 
Signature · 1 line
2.55.0
maintainer Applied
#11 lore raw

Patch "mptcp: close race between scheduler and state change" has been added to the 6.12-stable tree

This is a note to let you know that I've just added the patch titled

mptcp: close race between scheduler and state change

to the 6.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-close-race-between-scheduler-and-state-change.patch
and it can be found in the queue-6.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Sat Sep 19 21:57:24 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Sat, 19 Sep 2026 21:56:47 +0200
Subject: mptcp: close race between scheduler and state change
To: [email protected], [email protected], [email protected]
Cc: Paolo Abeni <[email protected]>, [email protected], Shardul Bankar <[email protected]>, Xinyang Ge <[email protected]>, "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: Paolo Abeni <[email protected]>

commit 42064de57fb83231fcc89663a94885f228a1ee53 upstream.

The mptcp scheduler may race with subflow sockets state change: data transmission on the selected socket may fail and a later release could try to use mss_now reset to 0 for a divide operation.

Address the issue by explicitly checking for the critical scenario.

---
 net/mptcp/protocol.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/mptcp/protocol.c +3 -1
@@ -1567,7 +1567,9 @@ struct sock *mptcp_subflow_get_send(stru
 
 static void mptcp_push_release(struct sock *ssk, struct mptcp_sendmsg_info *info)
 {
-	tcp_push(ssk, 0, info->mss_now, tcp_sk(ssk)->nonagle, info->size_goal);
+	if (info->mss_now)
+		tcp_push(ssk, 0, info->mss_now, tcp_sk(ssk)->nonagle,
+			 info->size_goal);
 	release_sock(ssk);
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-6.12/mptcp-annotate-data-races-around-subflow-fully_established.patch queue-6.12/selftests-mptcp-fix-an-uaf-in-mptcp_connect.c.patch queue-6.12/mptcp-fix-bad-accounting-in-__mptcp_subflow_push_pending.patch queue-6.12/mptcp-syncookies-remember-the-request-backup-flag.patch queue-6.12/mptcp-remove-unneeded-read_once-annotation.patch queue-6.12/mptcp-close-race-between-scheduler-and-state-change.patch queue-6.12/tcp-use-gfp_atomic-in-tcp_send_active_reset.patch queue-6.12/mptcp-avoid-unneeded-actions-on-subflow-reset.patch queue-6.12/mptcp-options-handle-mpc-data-csum-reqd-no-csum.patch queue-6.12/mptcp-subflow-no-need-to-copy-thmac-during-ulp_clone.patch

author maintainer
#12 lore raw

PATCH 5/5 mptcp: fix bad accounting in __mptcp_subflow_push_pending()

In reply to Matthieu Baerts (NGI0)

From: Paolo Abeni <[email protected]>

commit f3ef03357396d4b147d8e76c75fb612c2f264ffc upstream.

If __subflow_push_pending() errors out we should avoid updating the copied byte counters, to avoid mismatch push call later on.

---
 net/mptcp/protocol.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/mptcp/protocol.c +2 -1
index 1304f3cb6d14..ee160c783ff5 100644
@@ -1757,7 +1757,8 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
 			ret = __subflow_push_pending(sk, ssk, &info);
 			if (ret <= 0)
 				keep_pushing = false;
-			copied += ret;
+			else
+				copied += ret;
 		}
 
 		mptcp_for_each_subflow(msk, subflow) {
Signature · 1 line
2.55.0
maintainer Applied
#13 lore raw

Patch "mptcp: fix bad accounting in __mptcp_subflow_push_pending()" has been added to the 6.12-stable tree

This is a note to let you know that I've just added the patch titled

mptcp: fix bad accounting in __mptcp_subflow_push_pending()

to the 6.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-fix-bad-accounting-in-__mptcp_subflow_push_pending.patch
and it can be found in the queue-6.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Sat Sep 19 21:57:31 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Sat, 19 Sep 2026 21:56:48 +0200
Subject: mptcp: fix bad accounting in __mptcp_subflow_push_pending()
To: [email protected], [email protected], [email protected]
Cc: Paolo Abeni <[email protected]>, [email protected], "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: Paolo Abeni <[email protected]>

commit f3ef03357396d4b147d8e76c75fb612c2f264ffc upstream.

If __subflow_push_pending() errors out we should avoid updating the copied byte counters, to avoid mismatch push call later on.

---
 net/mptcp/protocol.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/mptcp/protocol.c +2 -1
@@ -1757,7 +1757,8 @@ static void __mptcp_subflow_push_pending
 			ret = __subflow_push_pending(sk, ssk, &info);
 			if (ret <= 0)
 				keep_pushing = false;
-			copied += ret;
+			else
+				copied += ret;
 		}
 
 		mptcp_for_each_subflow(msk, subflow) {

Patches currently in stable-queue which might be from [email protected] are

queue-6.12/mptcp-annotate-data-races-around-subflow-fully_established.patch queue-6.12/selftests-mptcp-fix-an-uaf-in-mptcp_connect.c.patch queue-6.12/mptcp-fix-bad-accounting-in-__mptcp_subflow_push_pending.patch queue-6.12/mptcp-syncookies-remember-the-request-backup-flag.patch queue-6.12/mptcp-remove-unneeded-read_once-annotation.patch queue-6.12/mptcp-close-race-between-scheduler-and-state-change.patch queue-6.12/tcp-use-gfp_atomic-in-tcp_send_active_reset.patch queue-6.12/mptcp-avoid-unneeded-actions-on-subflow-reset.patch queue-6.12/mptcp-options-handle-mpc-data-csum-reqd-no-csum.patch queue-6.12/mptcp-subflow-no-need-to-copy-thmac-during-ulp_clone.patch