• Neal Cardwell's avatar
    tcp: fix tcp_match_skb_to_sack() for unaligned SACK at end of an skb · 06c84e98
    Neal Cardwell authored
    [ Upstream commit 2cd0d743 ]
    
    If there is an MSS change (or misbehaving receiver) that causes a SACK
    to arrive that covers the end of an skb but is less than one MSS, then
    tcp_match_skb_to_sack() was rounding up pkt_len to the full length of
    the skb ("Round if necessary..."), then chopping all bytes off the skb
    and creating a zero-byte skb in the write queue.
    
    This was visible now because the recently simplified TLP logic in
    bef1909e ("tcp: fixing TLP's FIN recovery") could find that 0-byte
    skb at the end of the write queue, and now that we do not check that
    skb's length we could send it as a TLP probe.
    
    Consider the following example scenario:
    
     mss: 1000
     skb: seq: 0 end_seq: 4000  len: 4000
     SACK: start_seq: 3999 end_seq: 4000
    
    The tcp_match_skb_to_sack() code will compute:
    
     in_sack = false
     pkt_len = start_seq - TCP_SKB_CB(skb)->seq = 3999 - 0 = 3999
     new_len = (pkt_len / mss) * mss = (3999/1000)*1000 = 3000
     new_len += mss = 4000
    
    Previously we would find the new_len > skb->len check failing, so we
    would fall through and set pkt_len = new_len = 4000 and chop off
    pkt_len of 4000 from the 4000-byte skb, leaving a 0-byte segment
    afterward in the write queue.
    
    With this new commit, we notice that the new new_len >= skb->len check
    succeeds, so that we return without trying to fragment.
    
    Fixes: adb92db8 ("tcp: Make SACK code to split only at mss boundaries")
    Reported-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarNeal Cardwell <ncardwell@google.com>
    Cc: Eric Dumazet <edumazet@google.com>
    Cc: Yuchung Cheng <ycheng@google.com>
    Cc: Ilpo Jarvinen <ilpo.jarvinen@helsinki.fi>
    Acked-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    06c84e98
tcp_input.c 173 KB