mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 22:02:02 +00:00
mptcp: prevent tcp diag from closing listener subflows
commit4c0288299f
upstream. 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:57fc0f1cea
("mptcp: ensure listener is unhashed before updating the sk status") Cc: stable@vger.kernel.org Reported-by: <syzbot+5a01c3a666e726bc8752@syzkaller.appspotmail.com> Closes: https://lore.kernel.org/netdev/0000000000004f4579060c68431b@google.com/ Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts <matttbe@kernel.org> Link: https://lore.kernel.org/r/20231226-upstream-net-20231226-mptcp-prevent-warn-v1-2-1404dcc431ea@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
67df4c4a48
commit
c25546cac3
1 changed files with 13 additions and 0 deletions
|
@ -1974,6 +1974,17 @@ static void tcp_release_cb_override(struct sock *ssk)
|
|||
tcp_release_cb(ssk);
|
||||
}
|
||||
|
||||
static int tcp_abort_override(struct sock *ssk, int err)
|
||||
{
|
||||
/* closing a listener subflow requires a great deal of care.
|
||||
* keep it simple and just prevent such operation
|
||||
*/
|
||||
if (inet_sk_state_load(ssk) == TCP_LISTEN)
|
||||
return -EINVAL;
|
||||
|
||||
return tcp_abort(ssk, err);
|
||||
}
|
||||
|
||||
static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = {
|
||||
.name = "mptcp",
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -2018,6 +2029,7 @@ void __init mptcp_subflow_init(void)
|
|||
|
||||
tcp_prot_override = tcp_prot;
|
||||
tcp_prot_override.release_cb = tcp_release_cb_override;
|
||||
tcp_prot_override.diag_destroy = tcp_abort_override;
|
||||
|
||||
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
|
||||
/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
|
||||
|
@ -2054,6 +2066,7 @@ void __init mptcp_subflow_init(void)
|
|||
|
||||
tcpv6_prot_override = tcpv6_prot;
|
||||
tcpv6_prot_override.release_cb = tcp_release_cb_override;
|
||||
tcpv6_prot_override.diag_destroy = tcp_abort_override;
|
||||
#endif
|
||||
|
||||
mptcp_diag_subflow_init(&subflow_ulp_ops);
|
||||
|
|
Loading…
Reference in a new issue