The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH net] tcp: fix icsk_ack.ato bitfield overflow
@ 2026-08-07  1:44 Jiayuan Chen
  2026-08-07 17:16 ` Neal Cardwell
  0 siblings, 1 reply; 2+ messages in thread
From: Jiayuan Chen @ 2026-08-07  1:44 UTC (permalink / raw)
  To: netdev
  Cc: Jiayuan Chen, Eric Dumazet, Neal Cardwell, Kuniyuki Iwashima,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
	David Morley, Yuchung Cheng, linux-kernel

On cross-region connections we observed delayed ACKs suddenly turning
into immediate ACKs plus a TCP_MAX_QUICKACKS burst, as if the
connection had just received its first data segment.

Commit 95b9a87c6a6b ("tcp: record last received ipv6 flowlabel")
squeezed icsk_ack.ato into 8 bits, sized for TCP_DELACK_MAX. But both
writers still bound ato by icsk_rto, which can be well above 255
jiffies, so the bitfield assignment silently wraps mod 256: repeated
delack timer misses double ato up to icsk_rto, storing 320 as 64 and
256 as 0, and ato == 0 is the "first data packet" sentinel in
tcp_event_data_recv().

Clamp both writers to TCP_DELACK_MAX, which the static_assert already
guarantees to fit and tcp_send_delayed_ack() effectively caps ato at
anyway.

Fixes: 95b9a87c6a6b ("tcp: record last received ipv6 flowlabel")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
 net/ipv4/tcp_input.c | 6 +++---
 net/ipv4/tcp_timer.c | 4 +++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index daff93d51342..c0d2d3c0d40a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1039,9 +1039,9 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
 			/* The fastest case is the first. */
 			icsk->icsk_ack.ato = (icsk->icsk_ack.ato >> 1) + TCP_ATO_MIN / 2;
 		} else if (m < icsk->icsk_ack.ato) {
-			icsk->icsk_ack.ato = (icsk->icsk_ack.ato >> 1) + m;
-			if (icsk->icsk_ack.ato > icsk->icsk_rto)
-				icsk->icsk_ack.ato = icsk->icsk_rto;
+			icsk->icsk_ack.ato = min3((icsk->icsk_ack.ato >> 1) + (u32)m,
+						  icsk->icsk_rto,
+						  (u32)TCP_DELACK_MAX);
 		} else if (m > icsk->icsk_rto) {
 			/* Too long gap. Apparently sender failed to
 			 * restart window, so that we send ACKs quickly.
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index f7215d53bbda..1038e7ba9c2e 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -334,7 +334,9 @@ void tcp_delack_timer_handler(struct sock *sk)
 	if (inet_csk_ack_scheduled(sk)) {
 		if (!inet_csk_in_pingpong_mode(sk)) {
 			/* Delayed ACK missed: inflate ATO. */
-			icsk->icsk_ack.ato = min_t(u32, icsk->icsk_ack.ato << 1, icsk->icsk_rto);
+			icsk->icsk_ack.ato = min3((u32)icsk->icsk_ack.ato << 1,
+						  icsk->icsk_rto,
+						  (u32)TCP_DELACK_MAX);
 		} else {
 			/* Delayed ACK missed: leave pingpong mode and
 			 * deflate ATO.
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net] tcp: fix icsk_ack.ato bitfield overflow
  2026-08-07  1:44 [PATCH net] tcp: fix icsk_ack.ato bitfield overflow Jiayuan Chen
@ 2026-08-07 17:16 ` Neal Cardwell
  0 siblings, 0 replies; 2+ messages in thread
From: Neal Cardwell @ 2026-08-07 17:16 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: netdev, Eric Dumazet, Kuniyuki Iwashima, David S. Miller,
	Jakub Kicinski, Paolo Abeni, Simon Horman, David Morley,
	Yuchung Cheng, linux-kernel

On Thu, Aug 6, 2026 at 9:45 PM Jiayuan Chen <jiayuan.chen@linux.dev> wrote:
>
> On cross-region connections we observed delayed ACKs suddenly turning
> into immediate ACKs plus a TCP_MAX_QUICKACKS burst, as if the
> connection had just received its first data segment.
>
> Commit 95b9a87c6a6b ("tcp: record last received ipv6 flowlabel")
> squeezed icsk_ack.ato into 8 bits, sized for TCP_DELACK_MAX. But both
> writers still bound ato by icsk_rto, which can be well above 255
> jiffies, so the bitfield assignment silently wraps mod 256: repeated
> delack timer misses double ato up to icsk_rto, storing 320 as 64 and
> 256 as 0, and ato == 0 is the "first data packet" sentinel in
> tcp_event_data_recv().
>
> Clamp both writers to TCP_DELACK_MAX, which the static_assert already
> guarantees to fit and tcp_send_delayed_ack() effectively caps ato at
> anyway.
>
> Fixes: 95b9a87c6a6b ("tcp: record last received ipv6 flowlabel")
> Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>

Reviewed-by: Neal Cardwell <ncardwell@google.com>

Thanks for the fix!

neal

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-08-07 17:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07  1:44 [PATCH net] tcp: fix icsk_ack.ato bitfield overflow Jiayuan Chen
2026-08-07 17:16 ` Neal Cardwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox