All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrei Vagin <avagin@gmail.com>
To: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	David Ahern <dsahern@kernel.org>,
	Joanne Koong <joannelkoong@gmail.com>,
	Kuniyuki Iwashima <kuni1840@gmail.com>,
	netdev@vger.kernel.org
Subject: Re: [PATCH v2 net 3/6] tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address.
Date: Tue, 12 Sep 2023 00:25:58 -0700	[thread overview]
Message-ID: <ZQAShrVUokZR/WGs@google.com> (raw)
In-Reply-To: <20230911183700.60878-4-kuniyu@amazon.com>

On Mon, Sep 11, 2023 at 11:36:57AM -0700, Kuniyuki Iwashima wrote:
> 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: 28044fc1d495 ("net: Add a bhash2 table hashed by port and address")
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> ---
>  net/ipv4/inet_hashtables.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
> index a58b04052ca6..c32f5e28758b 100644
> --- a/net/ipv4/inet_hashtables.c
> +++ b/net/ipv4/inet_hashtables.c
> @@ -820,8 +820,13 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb,

Should we fix inet_bind2_bucket_addr_match too?

>  		return false;
>  
>  #if IS_ENABLED(CONFIG_IPV6)
> -	if (sk->sk_family != tb->family)
> +	if (sk->sk_family != tb->family) {
> +		if (sk->sk_family == AF_INET)
> +			return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) &&
> +				tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr;

I was wondering why we don't check a case when sk is AF_INET6 and tb is
AF_INET. I tried to run the next test:

import socket
sk4 = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sk6 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0)
sk4.bind(("127.0.0.1", 32773))
sk6.bind(("::ffff:127.0.0.1", 32773))

The second bind returned EADDRINUSE. It works as expected only because
inet_use_bhash2_on_bind returns false for all v4mapped addresses. This
doesn't look right, and I am not sure it was intentional. I think it can
to be changed this way:

@@ -158,7 +158,7 @@ static bool inet_use_bhash2_on_bind(const struct sock *sk)
                int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);

                return addr_type != IPV6_ADDR_ANY &&
-                       addr_type != IPV6_ADDR_MAPPED;
+                       !ipv6_addr_v4mapped_any(&sk->sk_v6_rcv_saddr);
        }
 #endif
        return sk->sk_rcv_saddr != htonl(INADDR_ANY);

As for this patch, I think it may be a good idea if bind2 buckets for
v4-mapped addresses are created with the AF_INET family and matching
ipv4 addresses.

> +
>  		return false;
> +	}
>  
>  	if (sk->sk_family == AF_INET6)
>  		return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr);

  parent reply	other threads:[~2023-09-12  7:26 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-11 18:36 [PATCH v2 net 0/6] tcp: Fix bind() regression for v4-mapped-v6 address Kuniyuki Iwashima
2023-09-11 18:36 ` [PATCH v2 net 1/6] tcp: Factorise sk_family-independent comparison in inet_bind2_bucket_match(_addr_any) Kuniyuki Iwashima
2023-09-12  4:48   ` Eric Dumazet
2023-09-11 18:36 ` [PATCH v2 net 2/6] tcp: Fix bind() regression for v4-mapped-v6 wildcard address Kuniyuki Iwashima
2023-09-12  4:58   ` Eric Dumazet
2023-09-11 18:36 ` [PATCH v2 net 3/6] tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address Kuniyuki Iwashima
2023-09-12  4:59   ` Eric Dumazet
2023-09-12  7:25   ` Andrei Vagin [this message]
2023-09-12  7:59     ` Kuniyuki Iwashima
2023-09-12 14:29       ` Andrei Vagin
2023-09-11 18:36 ` [PATCH v2 net 4/6] selftest: tcp: Fix address length in bind_wildcard.c Kuniyuki Iwashima
2023-09-11 18:36 ` [PATCH v2 net 5/6] selftest: tcp: Move expected_errno into each test case " Kuniyuki Iwashima
2023-09-11 18:37 ` [PATCH v2 net 6/6] selftest: tcp: Add v4-mapped-v6 cases " Kuniyuki Iwashima
2023-09-11 18:54 ` [PATCH v2 net 0/6] tcp: Fix bind() regression for v4-mapped-v6 address Martin KaFai Lau
2023-09-13  6:20 ` 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=ZQAShrVUokZR/WGs@google.com \
    --to=avagin@gmail.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=joannelkoong@gmail.com \
    --cc=kuba@kernel.org \
    --cc=kuni1840@gmail.com \
    --cc=kuniyu@amazon.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /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.