diff options
author | Paolo Abeni <pabeni@redhat.com> | 2020-07-23 13:02:30 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-07-23 11:47:24 -0700 |
commit | 53eb4c383deb97b59f1755fe3035ec7992488375 (patch) | |
tree | da573c7e720fe560e745789ad5ca6da2a16aaee7 /net | |
parent | b0977bb268db1df6decd3405903ca500721cdc5f (diff) |
mptcp: avoid data corruption on reinsert
When updating a partially acked data fragment, we
actually corrupt it. This is irrelevant till we send
data on a single subflow, as retransmitted data, if
any are discarded by the peer as duplicate, but it
will cause data corruption as soon as we will start
creating non backup subflows.
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Tested-by: Christoph Paasch <cpaasch@apple.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/mptcp/protocol.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 59c0eef807b3..254e6ef2b4e0 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -460,15 +460,20 @@ static void mptcp_clean_una(struct sock *sk) dfrag = mptcp_rtx_head(sk); if (dfrag && after64(snd_una, dfrag->data_seq)) { - u64 delta = dfrag->data_seq + dfrag->data_len - snd_una; + u64 delta = snd_una - dfrag->data_seq; + + if (WARN_ON_ONCE(delta > dfrag->data_len)) + goto out; dfrag->data_seq += delta; + dfrag->offset += delta; dfrag->data_len -= delta; dfrag_uncharge(sk, delta); cleaned = true; } +out: if (cleaned) { sk_mem_reclaim_partial(sk); |