Skip to content

Commit

Permalink
Merge branch 'mptcp-a-couple-of-fixes'
Browse files Browse the repository at this point in the history
Paolo Abeni says:

====================
mptcp: a couple of fixes

This series includes two related fixes addressing potential divide by 0
bugs in the MPTCP datapath.
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jan 13, 2021
2 parents ece9ab2 + 76e2a55 commit 584c19f
Showing 1 changed file with 18 additions and 46 deletions.
64 changes: 18 additions & 46 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ static bool mptcp_subflow_active(struct mptcp_subflow_context *subflow)
static bool tcp_can_send_ack(const struct sock *ssk)
{
return !((1 << inet_sk_state_load(ssk)) &
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE));
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN));
}

static void mptcp_send_ack(struct mptcp_sock *msk)
Expand Down Expand Up @@ -2642,11 +2642,12 @@ static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)

static int mptcp_disconnect(struct sock *sk, int flags)
{
/* Should never be called.
* inet_stream_connect() calls ->disconnect, but that
* refers to the subflow socket, not the mptcp one.
*/
WARN_ON_ONCE(1);
struct mptcp_subflow_context *subflow;
struct mptcp_sock *msk = mptcp_sk(sk);

__mptcp_flush_join_list(msk);
mptcp_for_each_subflow(msk, subflow)
tcp_disconnect(mptcp_subflow_tcp_sock(subflow), flags);
return 0;
}

Expand Down Expand Up @@ -3089,6 +3090,14 @@ bool mptcp_finish_join(struct sock *ssk)
return true;
}

static void mptcp_shutdown(struct sock *sk, int how)
{
pr_debug("sk=%p, how=%d", sk, how);

if ((how & SEND_SHUTDOWN) && mptcp_close_state(sk))
__mptcp_wr_shutdown(sk);
}

static struct proto mptcp_prot = {
.name = "MPTCP",
.owner = THIS_MODULE,
Expand All @@ -3098,7 +3107,7 @@ static struct proto mptcp_prot = {
.accept = mptcp_accept,
.setsockopt = mptcp_setsockopt,
.getsockopt = mptcp_getsockopt,
.shutdown = tcp_shutdown,
.shutdown = mptcp_shutdown,
.destroy = mptcp_destroy,
.sendmsg = mptcp_sendmsg,
.recvmsg = mptcp_recvmsg,
Expand Down Expand Up @@ -3344,43 +3353,6 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
return mask;
}

static int mptcp_shutdown(struct socket *sock, int how)
{
struct mptcp_sock *msk = mptcp_sk(sock->sk);
struct sock *sk = sock->sk;
int ret = 0;

pr_debug("sk=%p, how=%d", msk, how);

lock_sock(sk);

how++;
if ((how & ~SHUTDOWN_MASK) || !how) {
ret = -EINVAL;
goto out_unlock;
}

if (sock->state == SS_CONNECTING) {
if ((1 << sk->sk_state) &
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
sock->state = SS_DISCONNECTING;
else
sock->state = SS_CONNECTED;
}

sk->sk_shutdown |= how;
if ((how & SEND_SHUTDOWN) && mptcp_close_state(sk))
__mptcp_wr_shutdown(sk);

/* Wake up anyone sleeping in poll. */
sk->sk_state_change(sk);

out_unlock:
release_sock(sk);

return ret;
}

static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
Expand All @@ -3394,7 +3366,7 @@ static const struct proto_ops mptcp_stream_ops = {
.ioctl = inet_ioctl,
.gettstamp = sock_gettstamp,
.listen = mptcp_listen,
.shutdown = mptcp_shutdown,
.shutdown = inet_shutdown,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
Expand Down Expand Up @@ -3444,7 +3416,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
.ioctl = inet6_ioctl,
.gettstamp = sock_gettstamp,
.listen = mptcp_listen,
.shutdown = mptcp_shutdown,
.shutdown = inet_shutdown,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet6_sendmsg,
Expand Down

0 comments on commit 584c19f

Please sign in to comment.