diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ab7a4e5435a8..8560a9c6d382 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4812,18 +4812,20 @@ static enum skb_drop_reason tcp_sequence(const struct sock *sk, const struct tcphdr *th) { const struct tcp_sock *tp = tcp_sk(sk); + u32 seq_limit; if (before(end_seq, tp->rcv_wup)) return SKB_DROP_REASON_TCP_OLD_SEQUENCE; - if (unlikely(after(end_seq, tp->rcv_nxt + tcp_max_receive_window(tp)))) { + seq_limit = tp->rcv_nxt + tcp_max_receive_window(tp); + if (unlikely(after(end_seq, seq_limit))) { /* Some stacks are known to handle FIN incorrectly; allow the * FIN to extend beyond the window and check it in detail later. */ - if (!after(end_seq - th->fin, tp->rcv_nxt + tcp_receive_window(tp))) + if (!after(end_seq - th->fin, seq_limit)) return SKB_NOT_DROPPED_YET; - if (after(seq, tp->rcv_nxt + tcp_max_receive_window(tp))) + if (after(seq, seq_limit)) return SKB_DROP_REASON_TCP_INVALID_SEQUENCE; /* Only accept this packet if receive queue is empty. */