Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

netfilter: conntrack: correct window scaling with retransmitted SYN

commit c7aab4f17021 ("netfilter: nf_conntrack_tcp: re-init for syn packets
only") introduces a bug where SYNs in ORIGINAL direction on reused 5-tuple
result in incorrect window scale negotiation. This commit merged the SYN
re-initialization and simultaneous open or SYN retransmits cases. Merging
this block added the logic in tcp_init_sender() that performed window scale
negotiation to the retransmitted syn case. Previously. this would only
result in updating the sender's scale and flags. After the merge the
additional logic results in improperly clearing the scale in ORIGINAL
direction before any packets in the REPLY direction are received. This
results in packets incorrectly being marked invalid for being
out-of-window.

This can be reproduced with the following trace:

Packet Sequence:
> Flags [S], seq 1687765604, win 62727, options [.. wscale 7], length 0
> Flags [S], seq 1944817196, win 62727, options [.. wscale 7], length 0

In order to fix the issue, only evaluate window negotiation for packets
in the REPLY direction. This was tested with simultaneous open, fast
open, and the above reproduction.

Fixes: c7aab4f17021 ("netfilter: nf_conntrack_tcp: re-init for syn packets only")
Signed-off-by: Ryan Schaefer <ryanschf@amazon.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Ryan Schaefer and committed by
Pablo Neira Ayuso
fb366fc7 a2933a87

+6 -4
+6 -4
net/netfilter/nf_conntrack_proto_tcp.c
··· 457 457 const struct sk_buff *skb, 458 458 unsigned int dataoff, 459 459 const struct tcphdr *tcph, 460 - u32 end, u32 win) 460 + u32 end, u32 win, 461 + enum ip_conntrack_dir dir) 461 462 { 462 463 /* SYN-ACK in reply to a SYN 463 464 * or SYN from reply direction in simultaneous open. ··· 472 471 * Both sides must send the Window Scale option 473 472 * to enable window scaling in either direction. 474 473 */ 475 - if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && 474 + if (dir == IP_CT_DIR_REPLY && 475 + !(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && 476 476 receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) { 477 477 sender->td_scale = 0; 478 478 receiver->td_scale = 0; ··· 544 542 if (tcph->syn) { 545 543 tcp_init_sender(sender, receiver, 546 544 skb, dataoff, tcph, 547 - end, win); 545 + end, win, dir); 548 546 if (!tcph->ack) 549 547 /* Simultaneous open */ 550 548 return NFCT_TCP_ACCEPT; ··· 587 585 */ 588 586 tcp_init_sender(sender, receiver, 589 587 skb, dataoff, tcph, 590 - end, win); 588 + end, win, dir); 591 589 592 590 if (dir == IP_CT_DIR_REPLY && !tcph->ack) 593 591 return NFCT_TCP_ACCEPT;