lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251016040159.3534435-4-kuniyu@google.com>
Date: Thu, 16 Oct 2025 04:00:35 +0000
From: Kuniyuki Iwashima <kuniyu@...gle.com>
To: Eric Dumazet <edumazet@...gle.com>, Neal Cardwell <ncardwell@...gle.com>, 
	"David S. Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>
Cc: Simon Horman <horms@...nel.org>, Yuchung Cheng <ycheng@...gle.com>, 
	Willem de Bruijn <willemb@...gle.com>, Kuniyuki Iwashima <kuniyu@...gle.com>, 
	Kuniyuki Iwashima <kuni1840@...il.com>, netdev@...r.kernel.org
Subject: [PATCH v1 net-next 3/4] tcp: Don't acknowledge SYN+ACK payload to TFO
 fallback client.

Currently, SYN+ACK payload is acknowledged and queued even for a TFO
fallback client, which did not send SYN with payload.

For example, this packetdrill script does not fail, even though the
server does not send a TFO cookie.

   0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
  +0 sendto(3, ..., 0, MSG_FASTOPEN, ..., ...) = -1 EINPROGRESS (Operation is now in progress)
  +0 > S 0:0(0) <mss 1460,nop,nop,sackOK,nop,wscale 8,FO,nop,nop>
  +0 < S. 0:1000(1000) ack 1 win 5840 <mss 1040,nop,nop,sackOK,nop,wscale 6>
  +0 > . 1:1(0) ack 1001       // should be ack 1
  +0 read(3, ..., 1000) = 1000 // should fail with -EAGAIN

This is because tcp_rcv_fastopen_synack(), which handles SYN+ACK for
both TFO client and TFO fallback client, calls tcp_fastopen_add_skb()
unconditionally.

RFC 7413 (TCP Fast Open), in Section 3. Protocol Overview [0], states
that the SYN+ACK payload is only allowed when the server acknowledges
SYN data:

   3. If the server accepts the data in the SYN packet, it may send the
      response data before the handshake finishes.

Let's not call tcp_fastopen_add_skb() when the client did not send
SYN with payload.

Note that Linux does not send SYN+ACK with payload but FreeBSD
could as mentioned in the commit below. [1]

Link: https://datatracker.ietf.org/doc/html/rfc7413#section-3 #[0]
Link: https://cgit.freebsd.org/src/commit/?id=3f43239f21e357246696f1e8675178881d9ed5bc #[1]
Fixes: 61d2bcae99f66 ("tcp: fastopen: accept data/FIN present in SYNACK message")
Signed-off-by: Kuniyuki Iwashima <kuniyu@...gle.com>
---
 net/ipv4/tcp_input.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 8fc97f4d8a6b2..e1d3066782b57 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6552,6 +6552,9 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
 
 	tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp);
 
+	if (!tp->syn_data)
+		return false;
+
 	if (data) { /* Retransmit unacked data in SYN */
 		if (tp->total_retrans)
 			tp->fastopen_client_fail = TFO_SYN_RETRANSMITTED;
@@ -6564,16 +6567,14 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
 				LINUX_MIB_TCPFASTOPENACTIVEFAIL);
 		return true;
 	}
-	tp->syn_data_acked = tp->syn_data;
-	if (tp->syn_data_acked) {
-		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
-		/* SYN-data is counted as two separate packets in tcp_ack() */
-		if (tp->delivered > 1)
-			--tp->delivered;
-	}
 
-	tcp_fastopen_add_skb(sk, synack);
+	/* SYN-data is counted as two separate packets in tcp_ack() */
+	if (tp->delivered > 1)
+		--tp->delivered;
 
+	tp->syn_data_acked = 1;
+	tcp_fastopen_add_skb(sk, synack);
+	NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
 	return false;
 }
 
-- 
2.51.0.788.g6d19910ace-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ