Skip to content

Commit 4c02882

Browse files
Paolo Abenikuba-moo
authored andcommitted
mptcp: prevent tcp diag from closing listener subflows
The MPTCP protocol does not expect that any other entity could change the first subflow status when such socket is listening. Unfortunately the TCP diag interface allows aborting any TCP socket, including MPTCP listeners subflows. As reported by syzbot, that trigger a WARN() and could lead to later bigger trouble. The MPTCP protocol needs to do some MPTCP-level cleanup actions to properly shutdown the listener. To keep the fix simple, prevent entirely the diag interface from stopping such listeners. We could refine the diag callback in a later, larger patch targeting net-next. Fixes: 57fc0f1 ("mptcp: ensure listener is unhashed before updating the sk status") Cc: [email protected] Reported-by: <[email protected]> Closes: https://lore.kernel.org/netdev/[email protected]/ Signed-off-by: Paolo Abeni <[email protected]> Reviewed-by: Mat Martineau <[email protected]> Signed-off-by: Matthieu Baerts <[email protected]> Link: https://lore.kernel.org/r/20231226-upstream-net-20231226-mptcp-prevent-warn-v1-2-1404dcc431ea@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 118ba47 commit 4c02882

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

net/mptcp/subflow.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,6 +1982,17 @@ static void tcp_release_cb_override(struct sock *ssk)
19821982
tcp_release_cb(ssk);
19831983
}
19841984

1985+
static int tcp_abort_override(struct sock *ssk, int err)
1986+
{
1987+
/* closing a listener subflow requires a great deal of care.
1988+
* keep it simple and just prevent such operation
1989+
*/
1990+
if (inet_sk_state_load(ssk) == TCP_LISTEN)
1991+
return -EINVAL;
1992+
1993+
return tcp_abort(ssk, err);
1994+
}
1995+
19851996
static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = {
19861997
.name = "mptcp",
19871998
.owner = THIS_MODULE,
@@ -2026,6 +2037,7 @@ void __init mptcp_subflow_init(void)
20262037

20272038
tcp_prot_override = tcp_prot;
20282039
tcp_prot_override.release_cb = tcp_release_cb_override;
2040+
tcp_prot_override.diag_destroy = tcp_abort_override;
20292041

20302042
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
20312043
/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
@@ -2061,6 +2073,7 @@ void __init mptcp_subflow_init(void)
20612073

20622074
tcpv6_prot_override = tcpv6_prot;
20632075
tcpv6_prot_override.release_cb = tcp_release_cb_override;
2076+
tcpv6_prot_override.diag_destroy = tcp_abort_override;
20642077
#endif
20652078

20662079
mptcp_diag_subflow_init(&subflow_ulp_ops);

0 commit comments

Comments
 (0)