From: Florin Badita-Nistor <baditaflorin@gmail.com>
To: netdev@vger.kernel.org
Cc: edumazet@kernel.org, ncardwell@google.com, kuniyu@google.com,
davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com,
horms@kernel.org, shuah@kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH net-next v2 1/2] tcp: avoid false bind exhaustion with odd-sized port ranges
Date: Fri, 6 Nov 2026 19:14:41 +0200 [thread overview]
Message-ID: <20261106171442.31811-2-baditaflorin@gmail.com> (raw)
In-Reply-To: <20261106171442.31811-1-baditaflorin@gmail.com>
inet_csk_find_open_port() rounds the range length down to an even
number but keeps the original exclusive upper bound for wrapping.
For an odd-sized range, the two scans can therefore miss a valid port
and return EADDRINUSE while an eligible port remains free.
For example, restrict a TCP socket to IP_LOCAL_PORT_RANGE [40000, 40002]
and hold explicit binds on 40000 and 40001. bind(..., 0) always fails,
although an explicit bind to 40002 succeeds. Both IPv4 and IPv6 TCP and
MPTCP are affected. A namespace-wide odd-sized ip_local_port_range can
also trigger the failure without a per-socket range setting.
Keep the full length for the scan bound and wrapping. The two scans
then cover every candidate in an odd-sized range, with at most one
repeated candidate when exhausted. Even-sized candidate sequences
remain unchanged.
For odd-sized ranges, subtracting an odd remaining value when wrapping
flips parity. The first scan can therefore also select offsets of the
parity preferred by __inet_hash_connect(). Namespace-wide ranges with
same-parity endpoints already trigger a sysctl warning, while connect()
uses step 1 for a per-socket IP_LOCAL_PORT_RANGE.
This only fixes bind() allocation. The rounding in __inet_hash_connect()
for namespace-wide ranges is unchanged, so connect() can still miss a
port in an odd-sized namespace range.
The issue was triggered while developing port-range selftests with
Codex assistance, then confirmed using userspace reproducers on
unmodified kernels. No kernel instrumentation or fault injection was
needed. Booted x86-64 KVM kernels were tested against the regression
selftest, the full ip_local_port_range suite, and a Go net.Listen
reproducer. The Go reproducer fails 100/100 times per IP version before
the fix and 0/100 afterwards with a three-port namespace range and two
listeners occupying its first two ports.
Fixes: ea8add2b1903 ("tcp/dccp: better use of ephemeral ports in bind()")
Signed-off-by: Florin Badita-Nistor <baditaflorin@gmail.com>
---
net/ipv4/inet_connection_sock.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index e56beec43..755fcea35 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -343,8 +343,6 @@ inet_csk_find_open_port(const struct sock *sk, struct inet_bind_bucket **tb_ret,
low = half;
}
remaining = high - low;
- if (likely(remaining > 1))
- remaining &= ~1U;
offset = get_random_u32_below(remaining);
/* __inet_hash_connect() favors ports having @low parity
--
2.51.0
next prev parent reply other threads:[~2026-11-06 17:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 17:14 [PATCH net-next v2 0/2] tcp: fix false exhaustion of odd-sized bind port ranges Florin Badita-Nistor
2026-11-06 17:14 ` Florin Badita-Nistor [this message]
2026-11-10 6:45 ` [PATCH net-next v2 1/2] tcp: avoid false bind exhaustion with odd-sized " Kuniyuki Iwashima
2026-11-10 7:04 ` Eric Dumazet
2026-11-06 17:14 ` [PATCH net-next v2 2/2] selftests/net: cover odd-sized local port ranges with one free port Florin Badita-Nistor
2026-11-12 16:20 ` [PATCH net-next v2 0/2] tcp: fix false exhaustion of odd-sized bind port ranges patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261106171442.31811-2-baditaflorin@gmail.com \
--to=baditaflorin@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.