diff mbox series

[net,1/6] netfilter: conntrack: correct window scaling with retransmitted SYN

Message ID 20240131225943.7536-2-pablo@netfilter.org (mailing list archive)
State Accepted
Commit fb366fc7541a1de521ab3df58471746aa793b833
Delegated to: Netdev Maintainers
Headers show
Series [net,1/6] netfilter: conntrack: correct window scaling with retransmitted SYN | expand

Checks

Context Check Description
netdev/series_format success Pull request is its own cover letter
netdev/tree_selection success Clearly marked for net
netdev/ynl success SINGLE THREAD; Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1064 this patch: 1064
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 0 of 0 maintainers
netdev/build_clang success Errors and warnings before: 1081 this patch: 1081
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1081 this patch: 1081
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 34 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-02-01--15-00 (tests: 713)

Commit Message

Pablo Neira Ayuso Jan. 31, 2024, 10:59 p.m. UTC
From: Ryan Schaefer <ryanschf@amazon.com>

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>
---
 net/netfilter/nf_conntrack_proto_tcp.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

patchwork-bot+netdevbpf@kernel.org Feb. 1, 2024, 5:20 p.m. UTC | #1
Hello:

This series was applied to netdev/net.git (main)
by Pablo Neira Ayuso <pablo@netfilter.org>:

On Wed, 31 Jan 2024 23:59:38 +0100 you wrote:
> From: Ryan Schaefer <ryanschf@amazon.com>
> 
> 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.
> 
> [...]

Here is the summary with links:
  - [net,1/6] netfilter: conntrack: correct window scaling with retransmitted SYN
    https://git.kernel.org/netdev/net/c/fb366fc7541a
  - [net,2/6] netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV
    https://git.kernel.org/netdev/net/c/776d45164844
  - [net,3/6] netfilter: conntrack: check SCTP_CID_SHUTDOWN_ACK for vtag setting in sctp_new
    https://git.kernel.org/netdev/net/c/6e348067ee4b
  - [net,4/6] netfilter: ipset: fix performance regression in swap operation
    https://git.kernel.org/netdev/net/c/97f7cf1cd80e
  - [net,5/6] netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger
    https://git.kernel.org/netdev/net/c/259eb32971e9
  - [net,6/6] netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom expectations
    https://git.kernel.org/netdev/net/c/8059918a1377

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index e573be5afde7..ae493599a3ef 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -457,7 +457,8 @@  static void tcp_init_sender(struct ip_ct_tcp_state *sender,
 			    const struct sk_buff *skb,
 			    unsigned int dataoff,
 			    const struct tcphdr *tcph,
-			    u32 end, u32 win)
+			    u32 end, u32 win,
+			    enum ip_conntrack_dir dir)
 {
 	/* SYN-ACK in reply to a SYN
 	 * or SYN from reply direction in simultaneous open.
@@ -471,7 +472,8 @@  static void tcp_init_sender(struct ip_ct_tcp_state *sender,
 	 * Both sides must send the Window Scale option
 	 * to enable window scaling in either direction.
 	 */
-	if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
+	if (dir == IP_CT_DIR_REPLY &&
+	    !(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
 	      receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) {
 		sender->td_scale = 0;
 		receiver->td_scale = 0;
@@ -542,7 +544,7 @@  tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir,
 		if (tcph->syn) {
 			tcp_init_sender(sender, receiver,
 					skb, dataoff, tcph,
-					end, win);
+					end, win, dir);
 			if (!tcph->ack)
 				/* Simultaneous open */
 				return NFCT_TCP_ACCEPT;
@@ -585,7 +587,7 @@  tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir,
 		 */
 		tcp_init_sender(sender, receiver,
 				skb, dataoff, tcph,
-				end, win);
+				end, win, dir);
 
 		if (dir == IP_CT_DIR_REPLY && !tcph->ack)
 			return NFCT_TCP_ACCEPT;