Skip to content

Commit

Permalink
mptcp: prevent tcp diag from closing listener subflows
Browse files Browse the repository at this point in the history
commit 4c02882 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: 57fc0f1 ("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>
  • Loading branch information
Paolo Abeni authored and gregkh committed Jan 10, 2024
1 parent 105063f commit af9a530
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,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,
Expand Down Expand Up @@ -1942,6 +1953,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
Expand Down Expand Up @@ -1977,6 +1989,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);
Expand Down

0 comments on commit af9a530

Please sign in to comment.