From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from zg8tmtyylji0my4xnjeumjiw.icoremail.net (zg8tmtyylji0my4xnjeumjiw.icoremail.net [162.243.161.220]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 971F42DCC1C for ; Sat, 11 Jul 2026 07:28:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=162.243.161.220 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783754903; cv=none; b=puMqK6G+ygY+XBdgHP6gcalId7F22sxp++ySMWWPDU6HTFXrQw5K0tW7Ar0lmOEgN0sZ1/IlNd6KrUTkSmieemC2aOv+NdYffS9AUMOYI6K447EmOSIspyw3IqDheQNc8ZGUWkYq6vSZ+09weGXgWlM0TQzv4EX6s5aEVSktc9M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783754903; c=relaxed/simple; bh=dN0YisO8eOYqzk+peaRmRbArINnCu7nxFUDGOQN9Ddk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=rhjeBjQjS69z4/lYGIG+yj3DcPfBMB7gRZiETxH+0MKwyBYAOcPU31R1CXBdEx4juqlo9gtkMpO+eLHau9AXhOuMVmviEccT2M6fGJXGQIB10Dw3VtNM4bF46ity655LKj2CBQLjmjGKOyVt9RwQCbbSCxjTjSeiOk3CI35IG70= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lzu.edu.cn; spf=pass smtp.mailfrom=lzu.edu.cn; arc=none smtp.client-ip=162.243.161.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lzu.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=lzu.edu.cn Received: from enjou-Legion-Y7000P-2019 (unknown [123.114.53.210]) by app3 (Coremail) with SMTP id ywmowAA3dv6G8FFq7I5FAA--.58882S2; Sat, 11 Jul 2026 15:28:07 +0800 (CST) From: Ren Wei To: netdev@vger.kernel.org Cc: edumazet@google.com, ncardwell@google.com, kuniyu@google.com, davem@davemloft.net, pabeni@redhat.com, horms@kernel.org, yuantan098@gmail.com, yifanwucs@gmail.com, tomapufckgml@gmail.com, bird@lzu.edu.cn, roxy520tt@gmail.com, n05ec@lzu.edu.cn Subject: [PATCH net v4 1/1] tcp: bound SYN-ACK timers to reqsk timeout range Date: Sat, 11 Jul 2026 15:27:48 +0800 Message-ID: X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:ywmowAA3dv6G8FFq7I5FAA--.58882S2 X-Coremail-Antispam: 1UD129KBjvJXoWxKFW5WrWDJFykZw17tFy7Jrb_yoW7Zw1rpF ZrK39rJr1kAFy7trs2ya4DZF4xJw4rAr17WrsFgrZavFs7Jr4fZFWjgrWavF47tFWv9FW2 qF4vgryDC3Z8ZaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBF1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4x0Y4vEx4A2 jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS0I0E0xvYzxvE52 x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUGVWU XwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI4 8JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2xKxwCY1x0262kK e7AKxVWUtVW8ZwCY02Avz4vE14v_GF4l42xK82IYc2Ij64vIr41l42xK82IY6x8ErcxFaV Av8VW8WwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUGFAJUUUUU= X-CM-SenderInfo: zqqvvuo6o23hxhgxhubq/1tbiAQwFCWpQq1gMrAAAso From: Zhiling Zou tcp_synack_retries supplies the SYN-ACK retry limit used by request socket timers. The same effective limit can also come from TCP_SYNCNT through icsk_syn_retries, while TCP_DEFER_ACCEPT can keep an ACKed request alive until rskq_defer_accept is reached. The request socket timeout counter is incremented before it is used to compute the next timeout. tcp_reqsk_timeout() and the Fast Open SYN-ACK timer shift req->timeout by req->num_timeout. Excessive retry or defer-accept limits can therefore drive these timer paths into invalid shift counts before the request expires. Clamp the effective retry and defer-accept limits in the regular request socket timer path, clamp the Fast Open retry limit, and make the request socket timeout helper saturate before shifting. This keeps sysctl writes unchanged while bounding the timer calculations. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Yuan Tan Reported-by: Yifan Wu Reported-by: Juefei Pu Reported-by: Xin Liu Assisted-by: Codex:gpt-5.4 Signed-off-by: Zhiling Zou Signed-off-by: Ren Wei --- Changes in v4: - Drop the tcp_synack_retries sysctl maximum to preserve existing user-space behavior, and keep the runtime clamps at the timer usage sites. - v3 Link: https://lore.kernel.org/all/20260702095324.2995243-1-n05ec@lzu.edu.cn/ Changes in v3: - Order local variables in tcp_reqsk_timeout_sk() by reverse Christmas tree. - v2 Link: https://lore.kernel.org/all/20260630035009.55201-1-n05ec@lzu.edu.cn/ Changes in v2: - Keep the existing max_retries calculation in tcp_fastopen_synack_timer() and only add the clamp, avoiding code churn. - v1 Link: https://lore.kernel.org/all/02e24eb83639e9d7ecc623f000c60254bb5c40a5.1782643946.git.roxy520tt@gmail.com/ include/net/tcp.h | 19 +++++++++++++++---- net/ipv4/inet_connection_sock.c | 6 +++++- net/ipv4/tcp_timer.c | 3 ++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 6d376ea4d1c0..ee78436b8964 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -183,6 +183,7 @@ static_assert((1 << ATO_BITS) > TCP_DELACK_MAX); #define MAX_TCP_KEEPINTVL 32767 #define MAX_TCP_KEEPCNT 127 #define MAX_TCP_SYNCNT 127 +#define MAX_TCP_SYNACK_RETRIES 63 /* Ensure that TCP PAWS checks are relaxed after ~2147 seconds * to avoid overflows. This assumes a clock smaller than 1 Mhz. @@ -882,12 +883,22 @@ static inline u32 __tcp_set_rto(const struct tcp_sock *tp) return usecs_to_jiffies((tp->srtt_us >> 3) + tp->rttvar_us); } -static inline unsigned long tcp_reqsk_timeout(struct request_sock *req) +static inline unsigned long tcp_reqsk_timeout_sk(const struct sock *sk, + struct request_sock *req) { - u64 timeout = (u64)req->timeout << req->num_timeout; + u32 rto_max = tcp_rto_max(sk); + u64 timeout = req->timeout; + + if (req->num_timeout >= BITS_PER_TYPE(u64) || + timeout > U64_MAX >> req->num_timeout) + return rto_max; + + return (unsigned long)min_t(u64, timeout << req->num_timeout, rto_max); +} - return (unsigned long)min_t(u64, timeout, - tcp_rto_max(req->rsk_listener)); +static inline unsigned long tcp_reqsk_timeout(struct request_sock *req) +{ + return tcp_reqsk_timeout_sk(req->rsk_listener, req); } u32 tcp_delack_max(const struct sock *sk); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 56902bba5483..b74212bae3dd 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -1056,6 +1056,8 @@ static void reqsk_timer_handler(struct timer_list *t) net = sock_net(sk_listener); max_syn_ack_retries = READ_ONCE(icsk->icsk_syn_retries) ? : READ_ONCE(net->ipv4.sysctl_tcp_synack_retries); + max_syn_ack_retries = min_t(int, max_syn_ack_retries, + MAX_TCP_SYNACK_RETRIES); /* Normally all the openreqs are young and become mature * (i.e. converted to established socket) for first timeout. * If synack was not acknowledged for 1 second, it means @@ -1086,7 +1088,9 @@ static void reqsk_timer_handler(struct timer_list *t) } } - syn_ack_recalc(req, max_syn_ack_retries, READ_ONCE(queue->rskq_defer_accept), + syn_ack_recalc(req, max_syn_ack_retries, + min_t(u8, READ_ONCE(queue->rskq_defer_accept), + MAX_TCP_SYNACK_RETRIES), &expire, &resend); tcp_syn_ack_timeout(req); diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index bf171b5e1eb3..bbedf2b9e1bc 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -467,6 +467,7 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req) */ max_retries = READ_ONCE(icsk->icsk_syn_retries) ? : READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_synack_retries) + 1; + max_retries = min_t(int, max_retries, MAX_TCP_SYNACK_RETRIES); if (req->num_timeout >= max_retries) { tcp_write_err(sk); @@ -488,7 +489,7 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req) if (!tp->retrans_stamp) tp->retrans_stamp = tcp_time_stamp_ts(tp); tcp_reset_xmit_timer(sk, ICSK_TIME_RETRANS, - req->timeout << req->num_timeout, false); + tcp_reqsk_timeout_sk(sk, req), false); } static bool tcp_rtx_probe0_timed_out(const struct sock *sk, -- 2.43.0