netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
@ 2022-09-27  0:25 Martin KaFai Lau
  2022-09-28  3:49 ` Eric Dumazet
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Martin KaFai Lau @ 2022-09-27  0:25 UTC (permalink / raw)
  To: netdev
  Cc: David Miller, Eric Dumazet, Jakub Kicinski, kernel-team,
	Paolo Abeni, Joanne Koong, Alexander Potapenko, Martin KaFai Lau

From: Martin KaFai Lau <martin.lau@kernel.org>

The v6_rcv_saddr and rcv_saddr are inside a union in the
'struct inet_bind2_bucket'.  When searching a bucket by following the
bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
the sk->sk_family and there is no way to check if the inet_bind2_bucket
has a v6 or v4 address in the union.  This leads to an uninit-value
KMSAN report in [0] and also potentially incorrect matches.

This patch fixes it by adding a family member to the inet_bind2_bucket
and then tests 'sk->sk_family != tb->family' before matching
the sk's address to the tb's address.

Cc: Joanne Koong <joannelkoong@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Fixes: 28044fc1d495 ("net: Add a bhash2 table hashed by port and address")
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
---
 include/net/inet_hashtables.h |  3 +++
 net/ipv4/inet_hashtables.c    | 10 ++++++++++
 2 files changed, 13 insertions(+)

diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 9121ccab1fa1..3af1e927247d 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -95,6 +95,9 @@ struct inet_bind2_bucket {
 	possible_net_t		ib_net;
 	int			l3mdev;
 	unsigned short		port;
+#if IS_ENABLED(CONFIG_IPV6)
+	unsigned short		family;
+#endif
 	union {
 #if IS_ENABLED(CONFIG_IPV6)
 		struct in6_addr		v6_rcv_saddr;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 74e64aad5114..49db8c597eea 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -109,6 +109,7 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb,
 	tb->l3mdev    = l3mdev;
 	tb->port      = port;
 #if IS_ENABLED(CONFIG_IPV6)
+	tb->family    = sk->sk_family;
 	if (sk->sk_family == AF_INET6)
 		tb->v6_rcv_saddr = sk->sk_v6_rcv_saddr;
 	else
@@ -146,6 +147,9 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2,
 					 const struct sock *sk)
 {
 #if IS_ENABLED(CONFIG_IPV6)
+	if (sk->sk_family != tb2->family)
+		return false;
+
 	if (sk->sk_family == AF_INET6)
 		return ipv6_addr_equal(&tb2->v6_rcv_saddr,
 				       &sk->sk_v6_rcv_saddr);
@@ -791,6 +795,9 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb,
 				    int l3mdev, const struct sock *sk)
 {
 #if IS_ENABLED(CONFIG_IPV6)
+	if (sk->sk_family != tb->family)
+		return false;
+
 	if (sk->sk_family == AF_INET6)
 		return net_eq(ib2_net(tb), net) && tb->port == port &&
 			tb->l3mdev == l3mdev &&
@@ -807,6 +814,9 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
 #if IS_ENABLED(CONFIG_IPV6)
 	struct in6_addr addr_any = {};
 
+	if (sk->sk_family != tb->family)
+		return false;
+
 	if (sk->sk_family == AF_INET6)
 		return net_eq(ib2_net(tb), net) && tb->port == port &&
 			tb->l3mdev == l3mdev &&
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2022-09-27  0:25 [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket Martin KaFai Lau
@ 2022-09-28  3:49 ` Eric Dumazet
  2022-09-28  4:46   ` Martin KaFai Lau
  2022-09-29  2:20 ` patchwork-bot+netdevbpf
  2023-09-08 21:54 ` Andrei Vagin
  2 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2022-09-28  3:49 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: netdev, David Miller, Jakub Kicinski, kernel-team, Paolo Abeni,
	Joanne Koong, Alexander Potapenko, Martin KaFai Lau

On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau <kafai@fb.com> wrote:
>
> From: Martin KaFai Lau <martin.lau@kernel.org>
>
> The v6_rcv_saddr and rcv_saddr are inside a union in the
> 'struct inet_bind2_bucket'.  When searching a bucket by following the
> bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
> the sk->sk_family and there is no way to check if the inet_bind2_bucket
> has a v6 or v4 address in the union.  This leads to an uninit-value
> KMSAN report in [0] and also potentially incorrect matches.

I do not see the KMSAN report, is it missing from this changelog ?

Thanks.


>
> This patch fixes it by adding a family member to the inet_bind2_bucket
> and then tests 'sk->sk_family != tb->family' before matching
> the sk's address to the tb's address.


>
> Cc: Joanne Koong <joannelkoong@gmail.com>
> Cc: Alexander Potapenko <glider@google.com>
> Fixes: 28044fc1d495 ("net: Add a bhash2 table hashed by port and address")
> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
> ---
>  include/net/inet_hashtables.h |  3 +++
>  net/ipv4/inet_hashtables.c    | 10 ++++++++++
>  2 files changed, 13 insertions(+)
>
> diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
> index 9121ccab1fa1..3af1e927247d 100644
> --- a/include/net/inet_hashtables.h
> +++ b/include/net/inet_hashtables.h
> @@ -95,6 +95,9 @@ struct inet_bind2_bucket {
>         possible_net_t          ib_net;
>         int                     l3mdev;
>         unsigned short          port;
> +#if IS_ENABLED(CONFIG_IPV6)
> +       unsigned short          family;
> +#endif
>         union {
>  #if IS_ENABLED(CONFIG_IPV6)
>                 struct in6_addr         v6_rcv_saddr;
> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
> index 74e64aad5114..49db8c597eea 100644
> --- a/net/ipv4/inet_hashtables.c
> +++ b/net/ipv4/inet_hashtables.c
> @@ -109,6 +109,7 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb,
>         tb->l3mdev    = l3mdev;
>         tb->port      = port;
>  #if IS_ENABLED(CONFIG_IPV6)
> +       tb->family    = sk->sk_family;
>         if (sk->sk_family == AF_INET6)
>                 tb->v6_rcv_saddr = sk->sk_v6_rcv_saddr;
>         else
> @@ -146,6 +147,9 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2,
>                                          const struct sock *sk)
>  {
>  #if IS_ENABLED(CONFIG_IPV6)
> +       if (sk->sk_family != tb2->family)
> +               return false;
> +
>         if (sk->sk_family == AF_INET6)
>                 return ipv6_addr_equal(&tb2->v6_rcv_saddr,
>                                        &sk->sk_v6_rcv_saddr);
> @@ -791,6 +795,9 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb,
>                                     int l3mdev, const struct sock *sk)
>  {
>  #if IS_ENABLED(CONFIG_IPV6)
> +       if (sk->sk_family != tb->family)
> +               return false;
> +
>         if (sk->sk_family == AF_INET6)
>                 return net_eq(ib2_net(tb), net) && tb->port == port &&
>                         tb->l3mdev == l3mdev &&
> @@ -807,6 +814,9 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
>  #if IS_ENABLED(CONFIG_IPV6)
>         struct in6_addr addr_any = {};
>
> +       if (sk->sk_family != tb->family)
> +               return false;
> +
>         if (sk->sk_family == AF_INET6)
>                 return net_eq(ib2_net(tb), net) && tb->port == port &&
>                         tb->l3mdev == l3mdev &&
> --
> 2.30.2
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2022-09-28  3:49 ` Eric Dumazet
@ 2022-09-28  4:46   ` Martin KaFai Lau
  2022-09-28  5:07     ` Eric Dumazet
  0 siblings, 1 reply; 8+ messages in thread
From: Martin KaFai Lau @ 2022-09-28  4:46 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: netdev, David Miller, Jakub Kicinski, kernel-team, Paolo Abeni,
	Joanne Koong, Alexander Potapenko, Martin KaFai Lau

On 9/27/22 8:49 PM, Eric Dumazet wrote:
> On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau <kafai@fb.com> wrote:
>>
>> From: Martin KaFai Lau <martin.lau@kernel.org>
>>
>> The v6_rcv_saddr and rcv_saddr are inside a union in the
>> 'struct inet_bind2_bucket'.  When searching a bucket by following the
>> bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
>> the sk->sk_family and there is no way to check if the inet_bind2_bucket
>> has a v6 or v4 address in the union.  This leads to an uninit-value
>> KMSAN report in [0] and also potentially incorrect matches.
> 
> I do not see the KMSAN report, is it missing from this changelog ?

My bad. Forgot to paste the link in the commit message.  It is here:

https://lore.kernel.org/netdev/CAG_fn=Ud3zSW7AZWXc+asfMhZVL5ETnvuY44Pmyv4NPv-ijN-A@mail.gmail.com/


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2022-09-28  4:46   ` Martin KaFai Lau
@ 2022-09-28  5:07     ` Eric Dumazet
  2022-09-28 11:15       ` Alexander Potapenko
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2022-09-28  5:07 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: netdev, David Miller, Jakub Kicinski, kernel-team, Paolo Abeni,
	Joanne Koong, Alexander Potapenko, Martin KaFai Lau

On Tue, Sep 27, 2022 at 9:46 PM Martin KaFai Lau <martin.lau@linux.dev> wrote:
>
> On 9/27/22 8:49 PM, Eric Dumazet wrote:
> > On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau <kafai@fb.com> wrote:
> >>
> >> From: Martin KaFai Lau <martin.lau@kernel.org>
> >>
> >> The v6_rcv_saddr and rcv_saddr are inside a union in the
> >> 'struct inet_bind2_bucket'.  When searching a bucket by following the
> >> bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
> >> the sk->sk_family and there is no way to check if the inet_bind2_bucket
> >> has a v6 or v4 address in the union.  This leads to an uninit-value
> >> KMSAN report in [0] and also potentially incorrect matches.
> >
> > I do not see the KMSAN report, is it missing from this changelog ?
>
> My bad. Forgot to paste the link in the commit message.  It is here:
>
> https://lore.kernel.org/netdev/CAG_fn=Ud3zSW7AZWXc+asfMhZVL5ETnvuY44Pmyv4NPv-ijN-A@mail.gmail.com/

I see, thanks.

Reviewed-by: Eric Dumazet <edumazet@google.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2022-09-28  5:07     ` Eric Dumazet
@ 2022-09-28 11:15       ` Alexander Potapenko
  0 siblings, 0 replies; 8+ messages in thread
From: Alexander Potapenko @ 2022-09-28 11:15 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Martin KaFai Lau, netdev, David Miller, Jakub Kicinski,
	kernel-team, Paolo Abeni, Joanne Koong, Martin KaFai Lau

On Wed, Sep 28, 2022 at 7:07 AM Eric Dumazet <edumazet@google.com> wrote:
>
> On Tue, Sep 27, 2022 at 9:46 PM Martin KaFai Lau <martin.lau@linux.dev> wrote:
> >
> > On 9/27/22 8:49 PM, Eric Dumazet wrote:
> > > On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau <kafai@fb.com> wrote:
> > >>
> > >> From: Martin KaFai Lau <martin.lau@kernel.org>
> > >>
> > >> The v6_rcv_saddr and rcv_saddr are inside a union in the
> > >> 'struct inet_bind2_bucket'.  When searching a bucket by following the
> > >> bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
> > >> the sk->sk_family and there is no way to check if the inet_bind2_bucket
> > >> has a v6 or v4 address in the union.  This leads to an uninit-value
> > >> KMSAN report in [0] and also potentially incorrect matches.
> > >
> > > I do not see the KMSAN report, is it missing from this changelog ?
> >
> > My bad. Forgot to paste the link in the commit message.  It is here:
> >
> > https://lore.kernel.org/netdev/CAG_fn=Ud3zSW7AZWXc+asfMhZVL5ETnvuY44Pmyv4NPv-ijN-A@mail.gmail.com/
>
> I see, thanks.
>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
Tested-by: Alexander Potapenko <glider@google.com>

Thanks!


-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Liana Sebastian
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2022-09-27  0:25 [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket Martin KaFai Lau
  2022-09-28  3:49 ` Eric Dumazet
@ 2022-09-29  2:20 ` patchwork-bot+netdevbpf
  2023-09-08 21:54 ` Andrei Vagin
  2 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-09-29  2:20 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: netdev, davem, edumazet, kuba, kernel-team, pabeni, joannelkoong,
	glider, martin.lau

Hello:

This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 26 Sep 2022 17:25:44 -0700 you wrote:
> From: Martin KaFai Lau <martin.lau@kernel.org>
> 
> The v6_rcv_saddr and rcv_saddr are inside a union in the
> 'struct inet_bind2_bucket'.  When searching a bucket by following the
> bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
> the sk->sk_family and there is no way to check if the inet_bind2_bucket
> has a v6 or v4 address in the union.  This leads to an uninit-value
> KMSAN report in [0] and also potentially incorrect matches.
> 
> [...]

Here is the summary with links:
  - [net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
    https://git.kernel.org/netdev/net-next/c/5456262d2baa

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2022-09-27  0:25 [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket Martin KaFai Lau
  2022-09-28  3:49 ` Eric Dumazet
  2022-09-29  2:20 ` patchwork-bot+netdevbpf
@ 2023-09-08 21:54 ` Andrei Vagin
  2023-09-09  7:05   ` Kuniyuki Iwashima
  2 siblings, 1 reply; 8+ messages in thread
From: Andrei Vagin @ 2023-09-08 21:54 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: netdev, David Miller, Eric Dumazet, Jakub Kicinski, kernel-team,
	Paolo Abeni, Joanne Koong, Alexander Potapenko, Martin KaFai Lau

On Mon, Sep 26, 2022 at 05:25:44PM -0700, Martin KaFai Lau wrote:
> From: Martin KaFai Lau <martin.lau@kernel.org>
> 
> The v6_rcv_saddr and rcv_saddr are inside a union in the
> 'struct inet_bind2_bucket'.  When searching a bucket by following the
> bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
> the sk->sk_family and there is no way to check if the inet_bind2_bucket
> has a v6 or v4 address in the union.  This leads to an uninit-value
> KMSAN report in [0] and also potentially incorrect matches.
> 
> This patch fixes it by adding a family member to the inet_bind2_bucket
> and then tests 'sk->sk_family != tb->family' before matching
> the sk's address to the tb's address.

It seems this patch doesn't handle v4mapped addresses properly. One of
gVisor test started failing with this change:

socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET6, sin6_port=htons(0), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6_addr), sin6_scope_id=0}, 28) = 0
getsockname(3, {sa_family=AF_INET6, sin6_port=htons(33789), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6_addr), sin6_scope_id=0}, [28]) = 0
socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 4
bind(4, {sa_family=AF_INET6, sin6_port=htons(33789), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_scope_id=0}, 28) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 5
bind(5, {sa_family=AF_INET, sin_port=htons(33789), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

The test expects that the second bind returns EADDRINUSE.

Thanks,
Andrei

> 
> Cc: Joanne Koong <joannelkoong@gmail.com>
> Cc: Alexander Potapenko <glider@google.com>
> Fixes: 28044fc1d495 ("net: Add a bhash2 table hashed by port and address")
> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
> ---
>  include/net/inet_hashtables.h |  3 +++
>  net/ipv4/inet_hashtables.c    | 10 ++++++++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
> index 9121ccab1fa1..3af1e927247d 100644
> --- a/include/net/inet_hashtables.h
> +++ b/include/net/inet_hashtables.h
> @@ -95,6 +95,9 @@ struct inet_bind2_bucket {
>  	possible_net_t		ib_net;
>  	int			l3mdev;
>  	unsigned short		port;
> +#if IS_ENABLED(CONFIG_IPV6)
> +	unsigned short		family;
> +#endif
>  	union {
>  #if IS_ENABLED(CONFIG_IPV6)
>  		struct in6_addr		v6_rcv_saddr;
> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
> index 74e64aad5114..49db8c597eea 100644
> --- a/net/ipv4/inet_hashtables.c
> +++ b/net/ipv4/inet_hashtables.c
> @@ -109,6 +109,7 @@ static void inet_bind2_bucket_init(struct inet_bind2_bucket *tb,
>  	tb->l3mdev    = l3mdev;
>  	tb->port      = port;
>  #if IS_ENABLED(CONFIG_IPV6)
> +	tb->family    = sk->sk_family;
>  	if (sk->sk_family == AF_INET6)
>  		tb->v6_rcv_saddr = sk->sk_v6_rcv_saddr;
>  	else
> @@ -146,6 +147,9 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2,
>  					 const struct sock *sk)
>  {
>  #if IS_ENABLED(CONFIG_IPV6)
> +	if (sk->sk_family != tb2->family)
> +		return false;
> +
>  	if (sk->sk_family == AF_INET6)
>  		return ipv6_addr_equal(&tb2->v6_rcv_saddr,
>  				       &sk->sk_v6_rcv_saddr);
> @@ -791,6 +795,9 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb,
>  				    int l3mdev, const struct sock *sk)
>  {
>  #if IS_ENABLED(CONFIG_IPV6)
> +	if (sk->sk_family != tb->family)
> +		return false;
> +
>  	if (sk->sk_family == AF_INET6)
>  		return net_eq(ib2_net(tb), net) && tb->port == port &&
>  			tb->l3mdev == l3mdev &&
> @@ -807,6 +814,9 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
>  #if IS_ENABLED(CONFIG_IPV6)
>  	struct in6_addr addr_any = {};
>  
> +	if (sk->sk_family != tb->family)
> +		return false;
> +
>  	if (sk->sk_family == AF_INET6)
>  		return net_eq(ib2_net(tb), net) && tb->port == port &&
>  			tb->l3mdev == l3mdev &&
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket
  2023-09-08 21:54 ` Andrei Vagin
@ 2023-09-09  7:05   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 8+ messages in thread
From: Kuniyuki Iwashima @ 2023-09-09  7:05 UTC (permalink / raw)
  To: avagin
  Cc: davem, edumazet, glider, joannelkoong, kafai, kernel-team, kuba,
	martin.lau, netdev, pabeni, kuniyu

From: Andrei Vagin <avagin@gmail.com>
Date: Fri, 8 Sep 2023 14:54:12 -0700
> On Mon, Sep 26, 2022 at 05:25:44PM -0700, Martin KaFai Lau wrote:
> > From: Martin KaFai Lau <martin.lau@kernel.org>
> > 
> > The v6_rcv_saddr and rcv_saddr are inside a union in the
> > 'struct inet_bind2_bucket'.  When searching a bucket by following the
> > bhash2 hashtable chain, eg. inet_bind2_bucket_match, it is only using
> > the sk->sk_family and there is no way to check if the inet_bind2_bucket
> > has a v6 or v4 address in the union.  This leads to an uninit-value
> > KMSAN report in [0] and also potentially incorrect matches.
> > 
> > This patch fixes it by adding a family member to the inet_bind2_bucket
> > and then tests 'sk->sk_family != tb->family' before matching
> > the sk's address to the tb's address.
> 
> It seems this patch doesn't handle v4mapped addresses properly. One of
> gVisor test started failing with this change:
> 
> socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
> bind(3, {sa_family=AF_INET6, sin6_port=htons(0), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6_addr), sin6_scope_id=0}, 28) = 0
> getsockname(3, {sa_family=AF_INET6, sin6_port=htons(33789), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::ffff:0.0.0.0", &sin6_addr), sin6_scope_id=0}, [28]) = 0
> socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 4
> bind(4, {sa_family=AF_INET6, sin6_port=htons(33789), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_scope_id=0}, 28) = 0
> socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 5
> bind(5, {sa_family=AF_INET, sin_port=htons(33789), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
> 
> The test expects that the second bind returns EADDRINUSE.

Thanks for the report.

inet_bind2_bucket_match_addr_any() forgot to take care of
IPV6_ADDR_MAPPED inaddr_any case.

This change fixes the regression.  I'll post a patch after
checking other two functions that the commit touched.

---8<---
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 7876b7d703cb..6f2a8dba24fe 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -837,7 +837,9 @@ bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const
 		if (sk->sk_family == AF_INET)
 			return net_eq(ib2_net(tb), net) && tb->port == port &&
 				tb->l3mdev == l3mdev &&
-				ipv6_addr_any(&tb->v6_rcv_saddr);
+				(ipv6_addr_any(&tb->v6_rcv_saddr) ||
+				 (ipv6_addr_type(&tb->v6_rcv_saddr) == IPV6_ADDR_MAPPED &&
+				  tb->v6_rcv_saddr.s6_addr32[3] == 0));
 
 		return false;
 	}
---8<---

---8<---
[root@localhost ~]# python3
>>> from socket import *
>>> 
>>> s1 = socket(AF_INET6, SOCK_STREAM)
>>> s1.bind(('::ffff:0.0.0.0', 0))
>>> port = s1.getsockname()[1]
>>> 
>>> s2 = socket(AF_INET, SOCK_STREAM)
>>> s2.bind(('127.0.0.1', port))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 98] Address already in use
---8<---

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-09-09  7:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-27  0:25 [PATCH net-next] net: Fix incorrect address comparison when searching for a bind2 bucket Martin KaFai Lau
2022-09-28  3:49 ` Eric Dumazet
2022-09-28  4:46   ` Martin KaFai Lau
2022-09-28  5:07     ` Eric Dumazet
2022-09-28 11:15       ` Alexander Potapenko
2022-09-29  2:20 ` patchwork-bot+netdevbpf
2023-09-08 21:54 ` Andrei Vagin
2023-09-09  7:05   ` Kuniyuki Iwashima

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).