• Kuniyuki Iwashima's avatar
    tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-wildcard addresses. · ea111449
    Kuniyuki Iwashima authored
    Commit 5e07e672 ("tcp: Use bhash2 for v4-mapped-v6 non-wildcard
    address.") introduced bind() regression for v4-mapped-v6 address.
    
    When we bind() the following two addresses on the same port, the 2nd
    bind() should succeed but fails now.
    
      1. [::] w/ IPV6_ONLY
      2. ::ffff:127.0.0.1
    
    After the chagne, v4-mapped-v6 uses bhash2 instead of bhash to
    detect conflict faster, but I forgot to add a necessary change.
    
    During the 2nd bind(), inet_bind2_bucket_match_addr_any() returns
    the tb2 bucket of [::], and inet_bhash2_conflict() finally calls
    inet_bind_conflict(), which returns true, meaning conflict.
    
      inet_bhash2_addr_any_conflict
      |- inet_bind2_bucket_match_addr_any  <-- return [::] bucket
      `- inet_bhash2_conflict
         `- __inet_bhash2_conflict <-- checks IPV6_ONLY for AF_INET
            |                          but not for v4-mapped-v6 address
            `- inet_bind_conflict  <-- does not check address
    
    inet_bind_conflict() does not check socket addresses because
    __inet_bhash2_conflict() is expected to do so.
    
    However, it checks IPV6_V6ONLY attribute only against AF_INET
    socket, and not for v4-mapped-v6 address.
    
    As a result, v4-mapped-v6 address conflicts with v6-only wildcard
    address.
    
    To avoid that, let's add the missing test to use bhash2 for
    v4-mapped-v6 address.
    
    Fixes: 5e07e672 ("tcp: Use bhash2 for v4-mapped-v6 non-wildcard address.")
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Link: https://lore.kernel.org/r/20240326204251.51301-2-kuniyu@amazon.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    ea111449
inet_connection_sock.c 41.6 KB