• Kuniyuki Iwashima's avatar
    tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address. · c48ef9c4
    Kuniyuki Iwashima authored
    Since bhash2 was introduced, the example below does not work as expected.
    These two bind() should conflict, but the 2nd bind() now succeeds.
    
      from socket import *
    
      s1 = socket(AF_INET6, SOCK_STREAM)
      s1.bind(('::ffff:127.0.0.1', 0))
    
      s2 = socket(AF_INET, SOCK_STREAM)
      s2.bind(('127.0.0.1', s1.getsockname()[1]))
    
    During the 2nd bind() in inet_csk_get_port(), inet_bind2_bucket_find()
    fails to find the 1st socket's tb2, so inet_bind2_bucket_create() allocates
    a new tb2 for the 2nd socket.  Then, we call inet_csk_bind_conflict() that
    checks conflicts in the new tb2 by inet_bhash2_conflict().  However, the
    new tb2 does not include the 1st socket, thus the bind() finally succeeds.
    
    In this case, inet_bind2_bucket_match() must check if AF_INET6 tb2 has
    the conflicting v4-mapped-v6 address so that inet_bind2_bucket_find()
    returns the 1st socket's tb2.
    
    Note that if we bind two sockets to 127.0.0.1 and then ::FFFF:127.0.0.1,
    the 2nd bind() fails properly for the same reason mentinoed in the previous
    commit.
    
    Fixes: 28044fc1 ("net: Add a bhash2 table hashed by port and address")
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
    Acked-by: default avatarAndrei Vagin <avagin@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    c48ef9c4
inet_hashtables.c 33.9 KB