@@ -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}
@@ -4880,10 +4888,20 @@ static void tcp_ofo_queue(struct sock *sk)
48804888static bool tcp_prune_ofo_queue (struct sock * sk , const struct sk_buff * in_skb );
48814889static int tcp_prune_queue (struct sock * sk , const struct sk_buff * in_skb );
48824890
4883- static int tcp_try_rmem_schedule (struct sock * sk , struct sk_buff * skb ,
4891+ /* Check if this incoming skb can be added to socket receive queues
4892+ * while satisfying sk->sk_rcvbuf limit.
4893+ */
4894+ static bool tcp_can_ingest (const struct sock * sk , const struct sk_buff * skb )
4895+ {
4896+ unsigned int new_mem = atomic_read (& sk -> sk_rmem_alloc ) + skb -> truesize ;
4897+
4898+ return new_mem <= sk -> sk_rcvbuf ;
4899+ }
4900+
4901+ static int tcp_try_rmem_schedule (struct sock * sk , const struct sk_buff * skb ,
48844902 unsigned int size )
48854903{
4886- if (atomic_read ( & sk -> sk_rmem_alloc ) > sk -> sk_rcvbuf ||
4904+ if (! tcp_can_ingest ( sk , skb ) ||
48874905 !sk_rmem_schedule (sk , skb , size )) {
48884906
48894907 if (tcp_prune_queue (sk , skb ) < 0 )
@@ -4915,6 +4933,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
49154933 return ;
49164934 }
49174935
4936+ tcp_measure_rcv_mss (sk , skb );
49184937 /* Disable header prediction. */
49194938 tp -> pred_flags = 0 ;
49204939 inet_csk_schedule_ack (sk );
@@ -5498,7 +5517,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk, const struct sk_buff *in_skb)
54985517 tcp_drop_reason (sk , skb , SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE );
54995518 tp -> ooo_last_skb = rb_to_skb (prev );
55005519 if (!prev || goal <= 0 ) {
5501- if (atomic_read ( & sk -> sk_rmem_alloc ) <= sk -> sk_rcvbuf &&
5520+ if (tcp_can_ingest ( sk , skb ) &&
55025521 !tcp_under_memory_pressure (sk ))
55035522 break ;
55045523 goal = sk -> sk_rcvbuf >> 3 ;
@@ -5532,12 +5551,12 @@ static int tcp_prune_queue(struct sock *sk, const struct sk_buff *in_skb)
55325551
55335552 NET_INC_STATS (sock_net (sk ), LINUX_MIB_PRUNECALLED );
55345553
5535- if (atomic_read ( & sk -> sk_rmem_alloc ) >= sk -> sk_rcvbuf )
5554+ if (! tcp_can_ingest ( sk , in_skb ) )
55365555 tcp_clamp_window (sk );
55375556 else if (tcp_under_memory_pressure (sk ))
55385557 tcp_adjust_rcv_ssthresh (sk );
55395558
5540- if (atomic_read ( & sk -> sk_rmem_alloc ) <= sk -> sk_rcvbuf )
5559+ if (tcp_can_ingest ( sk , in_skb ) )
55415560 return 0 ;
55425561
55435562 tcp_collapse_ofo_queue (sk );
@@ -5547,15 +5566,15 @@ static int tcp_prune_queue(struct sock *sk, const struct sk_buff *in_skb)
55475566 NULL ,
55485567 tp -> copied_seq , tp -> rcv_nxt );
55495568
5550- if (atomic_read ( & sk -> sk_rmem_alloc ) <= sk -> sk_rcvbuf )
5569+ if (tcp_can_ingest ( sk , in_skb ) )
55515570 return 0 ;
55525571
55535572 /* Collapsing did not help, destructive actions follow.
55545573 * This must not ever occur. */
55555574
55565575 tcp_prune_ofo_queue (sk , in_skb );
55575576
5558- if (atomic_read ( & sk -> sk_rmem_alloc ) <= sk -> sk_rcvbuf )
5577+ if (tcp_can_ingest ( sk , in_skb ) )
55595578 return 0 ;
55605579
55615580 /* If we are really being abused, tell the caller to silently
@@ -5881,7 +5900,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
58815900
58825901step1 :
58835902 /* Step 1: check sequence number */
5884- reason = tcp_sequence (tp , TCP_SKB_CB (skb )-> seq , TCP_SKB_CB (skb )-> end_seq );
5903+ reason = tcp_sequence (sk , TCP_SKB_CB (skb )-> seq , TCP_SKB_CB (skb )-> end_seq );
58855904 if (reason ) {
58865905 /* RFC793, page 37: "In all states except SYN-SENT, all reset
58875906 * (RST) segments are validated by checking their SEQ-fields."
@@ -5892,6 +5911,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
58925911 if (!th -> rst ) {
58935912 if (th -> syn )
58945913 goto syn_challenge ;
5914+ NET_INC_STATS (sock_net (sk ), LINUX_MIB_BEYOND_WINDOW );
58955915 if (!tcp_oow_rate_limited (sock_net (sk ), skb ,
58965916 LINUX_MIB_TCPACKSKIPPEDSEQ ,
58975917 & tp -> last_oow_ack_time ))
@@ -6110,6 +6130,10 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
61106130 if (tcp_checksum_complete (skb ))
61116131 goto csum_error ;
61126132
6133+ if (after (TCP_SKB_CB (skb )-> end_seq ,
6134+ tp -> rcv_nxt + tcp_receive_window (tp )))
6135+ goto validate ;
6136+
61136137 if ((int )skb -> truesize > sk -> sk_forward_alloc )
61146138 goto step5 ;
61156139
@@ -6165,7 +6189,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
61656189 /*
61666190 * Standard slow path.
61676191 */
6168-
6192+ validate :
61696193 if (!tcp_validate_incoming (sk , skb , th , 1 ))
61706194 return ;
61716195
0 commit comments