• Kuniyuki Iwashima's avatar
    tcp: Fix bind() regression for v4-mapped-v6 wildcard address. · aa99e5f8
    Kuniyuki Iwashima authored
    Andrei Vagin reported bind() regression with strace logs.
    
    If we bind() a TCPv6 socket to ::FFFF:0.0.0.0 and then bind() a TCPv4
    socket to 127.0.0.1, the 2nd bind() should fail but now succeeds.
    
      from socket import *
    
      s1 = socket(AF_INET6, SOCK_STREAM)
      s1.bind(('::ffff:0.0.0.0', 0))
    
      s2 = socket(AF_INET, SOCK_STREAM)
      s2.bind(('127.0.0.1', s1.getsockname()[1]))
    
    During the 2nd bind(), 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 v4-mapped-v6 wildcard address.
    
    The example above does not work after commit 5456262d ("net: Fix
    incorrect address comparison when searching for a bind2 bucket"), but
    the blamed change is not the commit.
    
    Before the commit, the leading zeros of ::FFFF:0.0.0.0 were treated
    as 0.0.0.0, and the sequence above worked by chance.  Technically, this
    case has been broken since bhash2 was introduced.
    
    Note that if we bind() two sockets to 127.0.0.1 and then ::FFFF:0.0.0.0,
    the 2nd bind() fails properly because we fall back to using bhash to
    detect conflicts for the v4-mapped-v6 address.
    
    Fixes: 28044fc1 ("net: Add a bhash2 table hashed by port and address")
    Reported-by: default avatarAndrei Vagin <avagin@google.com>
    Closes: https://lore.kernel.org/netdev/ZPuYBOFC8zsK6r9T@google.com/Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    aa99e5f8
ipv6.h 38.1 KB