Skip to content

Commit d9ba993

Browse files
q2venkuba-moo
authored andcommitted
tcp: Fix bind() conflict check for dual-stack wildcard address.
Paul Holzinger reported [0] that commit 5456262 ("net: Fix incorrect address comparison when searching for a bind2 bucket") introduced a bind() regression. Paul also gave a nice repro that calls two types of bind() on the same port, both of which now succeed, but the second call should fail: bind(fd1, ::, port) + bind(fd2, 127.0.0.1, port) The cited commit added address family tests in three functions to fix the uninit-value KMSAN report. [1] However, the test added to inet_bind2_bucket_match_addr_any() removed a necessary conflict check; the dual-stack wildcard address no longer conflicts with an IPv4 non-wildcard address. If tb->family is AF_INET6 and sk->sk_family is AF_INET in inet_bind2_bucket_match_addr_any(), we still need to check if tb has the dual-stack wildcard address. Note that the IPv4 wildcard address does not conflict with IPv6 non-wildcard addresses. [0]: https://lore.kernel.org/netdev/[email protected]/ [1]: https://lore.kernel.org/netdev/CAG_fn=Ud3zSW7AZWXc+asfMhZVL5ETnvuY44Pmyv4NPv-ijN-A@mail.gmail.com/ Fixes: 5456262 ("net: Fix incorrect address comparison when searching for a bind2 bucket") Signed-off-by: Kuniyuki Iwashima <[email protected]> Reported-by: Paul Holzinger <[email protected]> Link: https://lore.kernel.org/netdev/CAG_fn=Ud3zSW7AZWXc+asfMhZVL5ETnvuY44Pmyv4NPv-ijN-A@mail.gmail.com/ Reviewed-by: Eric Dumazet <[email protected]> Tested-by: Paul Holzinger <[email protected]> Reviewed-by: Martin KaFai Lau <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c22c3bb commit d9ba993

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

net/ipv4/inet_hashtables.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,14 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
828828
#if IS_ENABLED(CONFIG_IPV6)
829829
struct in6_addr addr_any = {};
830830

831-
if (sk->sk_family != tb->family)
831+
if (sk->sk_family != tb->family) {
832+
if (sk->sk_family == AF_INET)
833+
return net_eq(ib2_net(tb), net) && tb->port == port &&
834+
tb->l3mdev == l3mdev &&
835+
ipv6_addr_equal(&tb->v6_rcv_saddr, &addr_any);
836+
832837
return false;
838+
}
833839

834840
if (sk->sk_family == AF_INET6)
835841
return net_eq(ib2_net(tb), net) && tb->port == port &&

0 commit comments

Comments
 (0)