Skip to content

Commit fb366fc

Browse files
Ryan Schaeferummakynes
authored andcommitted
netfilter: conntrack: correct window scaling with retransmitted SYN
commit c7aab4f ("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: c7aab4f ("netfilter: nf_conntrack_tcp: re-init for syn packets only") Signed-off-by: Ryan Schaefer <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent a2933a8 commit fb366fc

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

net/netfilter/nf_conntrack_proto_tcp.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender,
457457
const struct sk_buff *skb,
458458
unsigned int dataoff,
459459
const struct tcphdr *tcph,
460-
u32 end, u32 win)
460+
u32 end, u32 win,
461+
enum ip_conntrack_dir dir)
461462
{
462463
/* SYN-ACK in reply to a SYN
463464
* or SYN from reply direction in simultaneous open.
@@ -471,7 +472,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender,
471472
* Both sides must send the Window Scale option
472473
* to enable window scaling in either direction.
473474
*/
474-
if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
475+
if (dir == IP_CT_DIR_REPLY &&
476+
!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
475477
receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) {
476478
sender->td_scale = 0;
477479
receiver->td_scale = 0;
@@ -542,7 +544,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir,
542544
if (tcph->syn) {
543545
tcp_init_sender(sender, receiver,
544546
skb, dataoff, tcph,
545-
end, win);
547+
end, win, dir);
546548
if (!tcph->ack)
547549
/* Simultaneous open */
548550
return NFCT_TCP_ACCEPT;
@@ -585,7 +587,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir,
585587
*/
586588
tcp_init_sender(sender, receiver,
587589
skb, dataoff, tcph,
588-
end, win);
590+
end, win, dir);
589591

590592
if (dir == IP_CT_DIR_REPLY && !tcph->ack)
591593
return NFCT_TCP_ACCEPT;

0 commit comments

Comments
 (0)