--- /dev/null
+From stable+bounces-73016-greg=kroah.com@vger.kernel.org Wed Sep 4 13:11:38 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Wed, 4 Sep 2024 13:11:14 +0200
+Subject: mptcp: avoid duplicated SUB_CLOSED events
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: "MPTCP Upstream" <mptcp@lists.linux.dev>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, "Arınç ÜNAL" <arinc.unal@arinc9.com>, "Mat Martineau" <martineau@kernel.org>, "Paolo Abeni" <pabeni@redhat.com>
+Message-ID: <20240904111113.4092725-2-matttbe@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+commit d82809b6c5f2676b382f77a5cbeb1a5d91ed2235 upstream.
+
+The initial subflow might have already been closed, but still in the
+connection list. When the worker is instructed to close the subflows
+that have been marked as closed, it might then try to close the initial
+subflow again.
+
+ A consequence of that is that the SUB_CLOSED event can be seen twice:
+
+ # ip mptcp endpoint
+ 1.1.1.1 id 1 subflow dev eth0
+ 2.2.2.2 id 2 subflow dev eth1
+
+ # ip mptcp monitor &
+ [ CREATED] remid=0 locid=0 saddr4=1.1.1.1 daddr4=9.9.9.9
+ [ ESTABLISHED] remid=0 locid=0 saddr4=1.1.1.1 daddr4=9.9.9.9
+ [ SF_ESTABLISHED] remid=0 locid=2 saddr4=2.2.2.2 daddr4=9.9.9.9
+
+ # ip mptcp endpoint delete id 1
+ [ SF_CLOSED] remid=0 locid=0 saddr4=1.1.1.1 daddr4=9.9.9.9
+ [ SF_CLOSED] remid=0 locid=0 saddr4=1.1.1.1 daddr4=9.9.9.9
+
+The first one is coming from mptcp_pm_nl_rm_subflow_received(), and the
+second one from __mptcp_close_subflow().
+
+To avoid doing the post-closed processing twice, the subflow is now
+marked as closed the first time.
+
+Note that it is not enough to check if we are dealing with the first
+subflow and check its sk_state: the subflow might have been reset or
+closed before calling mptcp_close_ssk().
+
+Fixes: b911c97c7dc7 ("mptcp: add netlink event support")
+Cc: stable@vger.kernel.org
+Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+[ Conflict in protocol.h due to commit f1f26512a9bf ("mptcp: use plain
+ bool instead of custom binary enum"), commit dfc8d0603033 ("mptcp:
+ implement delayed seq generation for passive fastopen") and more that
+ are not in this version, because they modify the context and the size
+ of __unused. The conflict is easy to resolve, by not only adding the
+ new field (close_event_done), and __unused. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c | 6 ++++++
+ net/mptcp/protocol.h | 4 +++-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2503,6 +2503,12 @@ out:
+ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ struct mptcp_subflow_context *subflow)
+ {
++ /* The first subflow can already be closed and still in the list */
++ if (subflow->close_event_done)
++ return;
++
++ subflow->close_event_done = true;
++
+ if (sk->sk_state == TCP_ESTABLISHED)
+ mptcp_event(MPTCP_EVENT_SUB_CLOSED, mptcp_sk(sk), ssk, GFP_KERNEL);
+
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -479,7 +479,9 @@ struct mptcp_subflow_context {
+ can_ack : 1, /* only after processing the remote a key */
+ disposable : 1, /* ctx can be free at ulp release time */
+ stale : 1, /* unable to snd/rcv data, do not use for xmit */
+- valid_csum_seen : 1; /* at least one csum validated */
++ valid_csum_seen : 1, /* at least one csum validated */
++ close_event_done : 1, /* has done the post-closed part */
++ __unused : 9;
+ enum mptcp_data_avail data_avail;
+ u32 remote_nonce;
+ u64 thmac;