forked from mirrors/linux
		
	netfilter: nf_conntrack: fix tcp_in_window for Fast Open
Currently the conntrack checks if the ending sequence of a packet falls within the observed receive window. However it does so even if it has not observe any packet from the remote yet and uses an uninitialized receive window (td_maxwin). If a connection uses Fast Open to send a SYN-data packet which is dropped afterward in the network. The subsequent SYNs retransmits will all fail this check and be discarded, leading to a connection timeout. This is because the SYN retransmit does not contain data payload so end == initial sequence number (isn) + 1 sender->td_end == isn + syn_data_len receiver->td_maxwin == 0 The fix is to only apply this check after td_maxwin is initialized. Reported-by: Michael Chan <mcfchan@stanford.edu> Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
		
							parent
							
								
									e4d091d7bf
								
							
						
					
					
						commit
						356d7d88e0
					
				
					 1 changed files with 8 additions and 4 deletions
				
			
		|  | @ -526,7 +526,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | ||||||
| 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; | 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; | ||||||
| 	__u32 seq, ack, sack, end, win, swin; | 	__u32 seq, ack, sack, end, win, swin; | ||||||
| 	s16 receiver_offset; | 	s16 receiver_offset; | ||||||
| 	bool res; | 	bool res, in_recv_win; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Get the required data from the packet. | 	 * Get the required data from the packet. | ||||||
|  | @ -649,14 +649,18 @@ static bool tcp_in_window(const struct nf_conn *ct, | ||||||
| 		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, | 		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, | ||||||
| 		 receiver->td_scale); | 		 receiver->td_scale); | ||||||
| 
 | 
 | ||||||
|  | 	/* Is the ending sequence in the receive window (if available)? */ | ||||||
|  | 	in_recv_win = !receiver->td_maxwin || | ||||||
|  | 		      after(end, sender->td_end - receiver->td_maxwin - 1); | ||||||
|  | 
 | ||||||
| 	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n", | 	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n", | ||||||
| 		 before(seq, sender->td_maxend + 1), | 		 before(seq, sender->td_maxend + 1), | ||||||
| 		 after(end, sender->td_end - receiver->td_maxwin - 1), | 		 (in_recv_win ? 1 : 0), | ||||||
| 		 before(sack, receiver->td_end + 1), | 		 before(sack, receiver->td_end + 1), | ||||||
| 		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)); | 		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)); | ||||||
| 
 | 
 | ||||||
| 	if (before(seq, sender->td_maxend + 1) && | 	if (before(seq, sender->td_maxend + 1) && | ||||||
| 	    after(end, sender->td_end - receiver->td_maxwin - 1) && | 	    in_recv_win && | ||||||
| 	    before(sack, receiver->td_end + 1) && | 	    before(sack, receiver->td_end + 1) && | ||||||
| 	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) { | 	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) { | ||||||
| 		/*
 | 		/*
 | ||||||
|  | @ -725,7 +729,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | ||||||
| 			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, | 			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, | ||||||
| 			"nf_ct_tcp: %s ", | 			"nf_ct_tcp: %s ", | ||||||
| 			before(seq, sender->td_maxend + 1) ? | 			before(seq, sender->td_maxend + 1) ? | ||||||
| 			after(end, sender->td_end - receiver->td_maxwin - 1) ? | 			in_recv_win ? | ||||||
| 			before(sack, receiver->td_end + 1) ? | 			before(sack, receiver->td_end + 1) ? | ||||||
| 			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" | 			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" | ||||||
| 			: "ACK is under the lower bound (possible overly delayed ACK)" | 			: "ACK is under the lower bound (possible overly delayed ACK)" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Yuchung Cheng
						Yuchung Cheng