* [PATCH net 0/2] tcp/mptcp: prevent blackhole timeout arithmetic wraparound
@ 2026-11-10 15:47 Yingjie Wang
2026-11-10 15:47 ` [PATCH net 1/2] tcp: avoid wrapping Fast Open blackhole timeout Yingjie Wang
2026-11-10 15:48 ` [PATCH net 2/2] mptcp: avoid wrapping " Yingjie Wang
0 siblings, 2 replies; 3+ messages in thread
From: Yingjie Wang @ 2026-11-10 15:47 UTC (permalink / raw)
To: netdev
Cc: mptcp, linux-kernel, edumazet, ncardwell, kuniyu, davem, kuba,
pabeni, horms, matttbe, martineau, geliang, ycheng, weiwan
The TCP Fast Open and MPTCP blackhole handlers multiply writable timeout
sysctl values before adding the result to a jiffies timestamp. The
multiplication is performed in 32-bit unsigned arithmetic, so a large
value can wrap into a short delay even on a 64-bit kernel.
With HZ=1000, a timeout of 6912213 seconds and the maximum multiplier of
64 should produce 442381632000 jiffies, but the current calculations
truncate the result to 512 jiffies. Both patches compute the delay in u64
and cap it at MAX_JIFFY_OFFSET before adding it to the saved timestamp.
The issues were found using a static analysis tool. A loopback reproducer
induced 12 blackholes, waited 1.2 seconds, and then made a new connection:
TFO: base probe 1.026 s, TCPFastOpenActiveFail +1;
fixed probe 0.000 s, TCPFastOpenActiveFail +0.
MPTCP: base probe 3.087 s, MPCapableSYNTXDisabled +0;
fixed probe 0.000 s, MPCapableSYNTXDisabled +1.
The TFO counter records another failed active Fast Open attempt. The
MPTCP counter records a connection that skips MP_CAPABLE and falls back
to TCP while active MPTCP is disabled.
The base and fixed kernels used the same x86-64 HZ=1000 configuration.
The changed objects also build cleanly with W=1 under i386 defconfig,
with MPTCP, IPv6, and sysctl enabled. The i386 objects have no undefined
64-bit multiplication or division helper.
The current objects have identical disassembly and relocations to the
min_t() version on both architectures; the x86-64 objects also match
those from the runtime-tested kernel.
The runtime configuration had KASAN and UBSAN disabled. No BUG, WARNING,
or Oops diagnostic appeared. TCP and MPTCP selftests were not run.
The patches are independent and have separate Fixes tags.
Yingjie Wang (2):
tcp: avoid wrapping Fast Open blackhole timeout
mptcp: avoid wrapping blackhole timeout
net/ipv4/tcp_fastopen.c | 4 +++-
net/mptcp/ctrl.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
base-commit: 30c71476d842b094651bd7712f6c8ee8716147d0
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH net 1/2] tcp: avoid wrapping Fast Open blackhole timeout
2026-11-10 15:47 [PATCH net 0/2] tcp/mptcp: prevent blackhole timeout arithmetic wraparound Yingjie Wang
@ 2026-11-10 15:47 ` Yingjie Wang
2026-11-10 15:48 ` [PATCH net 2/2] mptcp: avoid wrapping " Yingjie Wang
1 sibling, 0 replies; 3+ messages in thread
From: Yingjie Wang @ 2026-11-10 15:47 UTC (permalink / raw)
To: netdev
Cc: mptcp, linux-kernel, edumazet, ncardwell, kuniyu, davem, kuba,
pabeni, horms, matttbe, martineau, geliang, ycheng, weiwan,
stable
tcp_fastopen_active_should_disable() calculates the active-disable
interval as multiplier * tfo_bh_timeout * HZ. Since all operands are
32-bit, a large tcp_fastopen_blackhole_timeout_sec can wrap the delay
even on 64-bit kernels and re-enable active Fast Open too soon.
For example, with HZ=1000, a timeout of 6912213 seconds and the maximum
multiplier of 64 should produce 442381632000 jiffies, but the current
calculation truncates it to 512 jiffies.
This issue was found using a static analysis tool. A loopback reproducer
induced 12 Fast Open blackholes and waited 1.2 seconds before opening
another connection. The unpatched kernel retried active Fast Open, while
the patched kernel kept Fast Open disabled and used a regular TCP
handshake. The reproducer required neither kernel modifications nor
fault injection.
Compute the interval in u64 and cap it at MAX_JIFFY_OFFSET before adding
it to the saved timestamp. This preserves the existing exponential
backoff for representable intervals and prevents large values from
wrapping into short timeouts.
Fixes: cf1ef3f0719b ("net/tcp_fastopen: Disable active side TFO in certain scenarios")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
net/ipv4/tcp_fastopen.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 7f7eb3cc1c04..aeefd605414f 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -613,6 +613,7 @@ bool tcp_fastopen_active_should_disable(struct sock *sk)
unsigned long timeout;
int tfo_da_times;
int multiplier;
+ u64 delay;
if (!tfo_bh_timeout)
return false;
@@ -626,10 +627,11 @@ bool tcp_fastopen_active_should_disable(struct sock *sk)
/* Limit timeout to max: 2^6 * initial timeout */
multiplier = 1 << min(tfo_da_times - 1, 6);
+ delay = (u64)multiplier * tfo_bh_timeout * HZ;
/* Paired with the WRITE_ONCE() in tcp_fastopen_active_disable(). */
timeout = READ_ONCE(sock_net(sk)->ipv4.tfo_active_disable_stamp) +
- multiplier * tfo_bh_timeout * HZ;
+ min(delay, MAX_JIFFY_OFFSET);
if (time_before(jiffies, timeout))
return true;
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH net 2/2] mptcp: avoid wrapping blackhole timeout
2026-11-10 15:47 [PATCH net 0/2] tcp/mptcp: prevent blackhole timeout arithmetic wraparound Yingjie Wang
2026-11-10 15:47 ` [PATCH net 1/2] tcp: avoid wrapping Fast Open blackhole timeout Yingjie Wang
@ 2026-11-10 15:48 ` Yingjie Wang
1 sibling, 0 replies; 3+ messages in thread
From: Yingjie Wang @ 2026-11-10 15:48 UTC (permalink / raw)
To: netdev
Cc: mptcp, linux-kernel, edumazet, ncardwell, kuniyu, davem, kuba,
pabeni, horms, matttbe, martineau, geliang, ycheng, weiwan,
stable
mptcp_active_should_disable() calculates the active-disable interval as
multiplier * blackhole_timeout * HZ. Since all operands are 32-bit, a
large blackhole_timeout can wrap the delay even on 64-bit kernels and
make active MPTCP available again while the blackhole is still present.
For example, with HZ=1000, a timeout of 6912213 seconds and the maximum
multiplier of 64 should produce 442381632000 jiffies, but the current
calculation truncates it to 512 jiffies.
This issue was found using a static analysis tool. A loopback reproducer
induced 12 MPTCP blackholes and waited 1.2 seconds before opening another
connection. The unpatched kernel retried MP_CAPABLE, while the patched
kernel kept MPTCP disabled and used TCP fallback directly. The reproducer
required neither kernel modifications nor fault injection.
Compute the interval in u64 and cap it at MAX_JIFFY_OFFSET before adding
it to the saved timestamp. This preserves the existing exponential
backoff for representable intervals and prevents large values from
wrapping into short timeouts.
Fixes: 27069e7cb3d1 ("mptcp: disable active MPTCP in case of blackhole")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
---
net/mptcp/ctrl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
index 63c5747f0f63..5224cfb3ed1f 100644
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -487,6 +487,7 @@ bool mptcp_active_should_disable(struct sock *ssk)
unsigned long timeout;
int disable_times;
int multiplier;
+ u64 delay;
pernet = mptcp_get_pernet(net);
blackhole_timeout = READ_ONCE(pernet->blackhole_timeout);
@@ -503,10 +504,11 @@ bool mptcp_active_should_disable(struct sock *ssk)
/* Limit timeout to max: 2^6 * initial timeout */
multiplier = 1 << min(disable_times - 1, 6);
+ delay = (u64)multiplier * blackhole_timeout * HZ;
/* Paired with the WRITE_ONCE() in mptcp_active_disable(). */
timeout = READ_ONCE(pernet->active_disable_stamp) +
- multiplier * blackhole_timeout * HZ;
+ min(delay, MAX_JIFFY_OFFSET);
return time_before(jiffies, timeout);
}
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-10 15:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10 15:47 [PATCH net 0/2] tcp/mptcp: prevent blackhole timeout arithmetic wraparound Yingjie Wang
2026-11-10 15:47 ` [PATCH net 1/2] tcp: avoid wrapping Fast Open blackhole timeout Yingjie Wang
2026-11-10 15:48 ` [PATCH net 2/2] mptcp: avoid wrapping " Yingjie Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®