Skip to content

Commit 9ca48d6

Browse files
edumazetkuba-moo
authored andcommitted
tcp: do not accept packets beyond window
Currently, TCP accepts incoming packets which might go beyond the offered RWIN. Add to tcp_sequence() the validation of packet end sequence. Add the corresponding check in the fast path. We relax this new constraint if the receive queue is empty, to not freeze flows from buggy peers. Add a new drop reason : SKB_DROP_REASON_TCP_INVALID_END_SEQUENCE. Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a86eb2a commit 9ca48d6

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

include/net/dropreason-core.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
FN(TCP_LISTEN_OVERFLOW) \
4646
FN(TCP_OLD_SEQUENCE) \
4747
FN(TCP_INVALID_SEQUENCE) \
48+
FN(TCP_INVALID_END_SEQUENCE) \
4849
FN(TCP_INVALID_ACK_SEQUENCE) \
4950
FN(TCP_RESET) \
5051
FN(TCP_INVALID_SYN) \
@@ -303,8 +304,13 @@ enum skb_drop_reason {
303304
SKB_DROP_REASON_TCP_LISTEN_OVERFLOW,
304305
/** @SKB_DROP_REASON_TCP_OLD_SEQUENCE: Old SEQ field (duplicate packet) */
305306
SKB_DROP_REASON_TCP_OLD_SEQUENCE,
306-
/** @SKB_DROP_REASON_TCP_INVALID_SEQUENCE: Not acceptable SEQ field */
307+
/** @SKB_DROP_REASON_TCP_INVALID_SEQUENCE: Not acceptable SEQ field. */
307308
SKB_DROP_REASON_TCP_INVALID_SEQUENCE,
309+
/**
310+
* @SKB_DROP_REASON_TCP_INVALID_END_SEQUENCE:
311+
* Not acceptable END_SEQ field.
312+
*/
313+
SKB_DROP_REASON_TCP_INVALID_END_SEQUENCE,
308314
/**
309315
* @SKB_DROP_REASON_TCP_INVALID_ACK_SEQUENCE: Not acceptable ACK SEQ
310316
* field because ack sequence is not in the window between snd_una

net/ipv4/tcp_input.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4391,14 +4391,22 @@ static enum skb_drop_reason tcp_disordered_ack_check(const struct sock *sk,
43914391
* (borrowed from freebsd)
43924392
*/
43934393

4394-
static enum skb_drop_reason tcp_sequence(const struct tcp_sock *tp,
4394+
static enum skb_drop_reason tcp_sequence(const struct sock *sk,
43954395
u32 seq, u32 end_seq)
43964396
{
4397+
const struct tcp_sock *tp = tcp_sk(sk);
4398+
43974399
if (before(end_seq, tp->rcv_wup))
43984400
return SKB_DROP_REASON_TCP_OLD_SEQUENCE;
43994401

4400-
if (after(seq, tp->rcv_nxt + tcp_receive_window(tp)))
4401-
return SKB_DROP_REASON_TCP_INVALID_SEQUENCE;
4402+
if (after(end_seq, tp->rcv_nxt + tcp_receive_window(tp))) {
4403+
if (after(seq, tp->rcv_nxt + tcp_receive_window(tp)))
4404+
return SKB_DROP_REASON_TCP_INVALID_SEQUENCE;
4405+
4406+
/* Only accept this packet if receive queue is empty. */
4407+
if (skb_queue_len(&sk->sk_receive_queue))
4408+
return SKB_DROP_REASON_TCP_INVALID_END_SEQUENCE;
4409+
}
44024410

44034411
return SKB_NOT_DROPPED_YET;
44044412
}
@@ -5881,7 +5889,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
58815889

58825890
step1:
58835891
/* Step 1: check sequence number */
5884-
reason = tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
5892+
reason = tcp_sequence(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
58855893
if (reason) {
58865894
/* RFC793, page 37: "In all states except SYN-SENT, all reset
58875895
* (RST) segments are validated by checking their SEQ-fields."
@@ -6110,6 +6118,10 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
61106118
if (tcp_checksum_complete(skb))
61116119
goto csum_error;
61126120

6121+
if (after(TCP_SKB_CB(skb)->end_seq,
6122+
tp->rcv_nxt + tcp_receive_window(tp)))
6123+
goto validate;
6124+
61136125
if ((int)skb->truesize > sk->sk_forward_alloc)
61146126
goto step5;
61156127

@@ -6165,7 +6177,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
61656177
/*
61666178
* Standard slow path.
61676179
*/
6168-
6180+
validate:
61696181
if (!tcp_validate_incoming(sk, skb, th, 1))
61706182
return;
61716183

0 commit comments

Comments
 (0)