Skip to content

Commit

Permalink
Squash-to: "mptcp: give rcvlowat some love"
Browse files Browse the repository at this point in the history
Christoph reported a couple of serious splat caused by
the mentioned patch.

mptcp_set_rcvlowat() can use msk->scaling_ratio, before
such field is initialized, causing a divide by zero: we
need to init it in the sock constructor.

Additionally the same function bogusly cast an msk to a
tcp_sock, causing memory corruption. The reproducer likely
clears the sk refcount for the next msk allocated into the
same slab.

The intent was to properly propagate the rcvbuf changes to
the subflows. Let's do that explicitly.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--
Closes: multipath-tcp/mptcp_net-next#442
Closes: multipath-tcp/mptcp_net-next#443

since the above issues are introduced by the squash-to patch, I think
we can't have the tag in the final patch.
  • Loading branch information
Paolo Abeni authored and intel-lab-lkp committed Sep 28, 2023
1 parent 6070d1d commit 8bb7278
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
2 changes: 2 additions & 0 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -2758,6 +2758,8 @@ static void __mptcp_init_sock(struct sock *sk)
msk->rmem_fwd_alloc = 0;
WRITE_ONCE(msk->rmem_released, 0);
msk->timer_ival = TCP_RTO_MIN;
msk->scaling_ratio = (1200 << TCP_RMEM_TO_WIN_SCALE) /
SKB_TRUESIZE(4096);

WRITE_ONCE(msk->first, NULL);
inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss;
Expand Down
17 changes: 14 additions & 3 deletions net/mptcp/sockopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,7 @@ void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk)
*/
int mptcp_set_rcvlowat(struct sock *sk, int val)
{
struct mptcp_subflow_context *subflow;
int space, cap;

if (sk->sk_userlocks & SOCK_RCVBUF_LOCK)
Expand All @@ -1490,9 +1491,19 @@ int mptcp_set_rcvlowat(struct sock *sk, int val)
return 0;

space = __tcp_space_from_win(mptcp_sk(sk)->scaling_ratio, val);
if (space > sk->sk_rcvbuf) {
WRITE_ONCE(sk->sk_rcvbuf, space);
tcp_sk(sk)->window_clamp = val;
if (space <= sk->sk_rcvbuf)
return 0;

/* propagate the rcvbuf changes to all the subflows */
WRITE_ONCE(sk->sk_rcvbuf, space);
mptcp_for_each_subflow(mptcp_sk(sk), subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
bool slow;

slow = lock_sock_fast(ssk);
WRITE_ONCE(ssk->sk_rcvbuf, space);
tcp_sk(ssk)->window_clamp = val;
unlock_sock_fast(ssk, slow);
}
return 0;
}

0 comments on commit 8bb7278

Please sign in to comment.