This is a note to let you know that I've just added the patch titled mptcp: fix possible list corruption on passive MPJ to the 6.1-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-possible-list-corruption-on-passive-mpj.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 56a666c48b038e91b76471289e2cf60c79d326b9 Mon Sep 17 00:00:00 2001 From: Paolo Abeni <pabeni@xxxxxxxxxx> Date: Tue, 20 Jun 2023 18:24:20 +0200 Subject: mptcp: fix possible list corruption on passive MPJ From: Paolo Abeni <pabeni@xxxxxxxxxx> commit 56a666c48b038e91b76471289e2cf60c79d326b9 upstream. At passive MPJ time, if the msk socket lock is held by the user, the new subflow is appended to the msk->join_list under the msk data lock. In mptcp_release_cb()/__mptcp_flush_join_list(), the subflows in that list are moved from the join_list into the conn_list under the msk socket lock. Append and removal could race, possibly corrupting such list. Address the issue splicing the join list into a temporary one while still under the msk data lock. Found by code inspection, the race itself should be almost impossible to trigger in practice. Fixes: 3e5014909b56 ("mptcp: cleanup MPJ subflow list handling") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx> Reviewed-by: Matthieu Baerts <matthieu.baerts@xxxxxxxxxxxx> Signed-off-by: Matthieu Baerts <matthieu.baerts@xxxxxxxxxxxx> Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/mptcp/protocol.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -846,12 +846,12 @@ static bool __mptcp_finish_join(struct m return true; } -static void __mptcp_flush_join_list(struct sock *sk) +static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_list) { struct mptcp_subflow_context *tmp, *subflow; struct mptcp_sock *msk = mptcp_sk(sk); - list_for_each_entry_safe(subflow, tmp, &msk->join_list, node) { + list_for_each_entry_safe(subflow, tmp, join_list, node) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); bool slow = lock_sock_fast(ssk); @@ -3335,9 +3335,14 @@ static void mptcp_release_cb(struct sock for (;;) { unsigned long flags = (msk->cb_flags & MPTCP_FLAGS_PROCESS_CTX_NEED) | msk->push_pending; + struct list_head join_list; + if (!flags) break; + INIT_LIST_HEAD(&join_list); + list_splice_init(&msk->join_list, &join_list); + /* the following actions acquire the subflow socket lock * * 1) can't be invoked in atomic scope @@ -3348,8 +3353,9 @@ static void mptcp_release_cb(struct sock msk->push_pending = 0; msk->cb_flags &= ~flags; spin_unlock_bh(&sk->sk_lock.slock); + if (flags & BIT(MPTCP_FLUSH_JOIN_LIST)) - __mptcp_flush_join_list(sk); + __mptcp_flush_join_list(sk, &join_list); if (flags & BIT(MPTCP_PUSH_PENDING)) __mptcp_push_pending(sk, 0); if (flags & BIT(MPTCP_RETRANSMIT)) Patches currently in stable-queue which might be from pabeni@xxxxxxxxxx are queue-6.1/mptcp-consolidate-fallback-and-non-fallback-state-machine.patch queue-6.1/mptcp-fix-possible-divide-by-zero-in-recvmsg.patch queue-6.1/selftests-mptcp-remove-duplicated-entries-in-usage.patch queue-6.1/mptcp-fix-possible-list-corruption-on-passive-mpj.patch queue-6.1/mptcp-handle-correctly-disconnect-failures.patch