From: Martin KaFai Lau <hidden> Date: 2022-09-27 00:26:02
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(+)
From: Eric Dumazet <edumazet@google.com> Date: 2022-09-28 03:50:14
On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau [off-list ref] 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.
quoted hunk
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(+)
From: Martin KaFai Lau <martin.lau@linux.dev> Date: 2022-09-28 04:47:01
On 9/27/22 8:49 PM, Eric Dumazet wrote:
On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau [off-list ref] wrote:
quoted
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 ?
From: Eric Dumazet <edumazet@google.com> Date: 2022-09-28 05:07:24
On Tue, Sep 27, 2022 at 9:46 PM Martin KaFai Lau [off-list ref] wrote:
On 9/27/22 8:49 PM, Eric Dumazet wrote:
quoted
On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau [off-list ref] wrote:
quoted
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 ?
From: Alexander Potapenko <glider@google.com> Date: 2022-09-28 11:16:32
On Wed, Sep 28, 2022 at 7:07 AM Eric Dumazet [off-list ref] wrote:
On Tue, Sep 27, 2022 at 9:46 PM Martin KaFai Lau [off-list ref] wrote:
quoted
On 9/27/22 8:49 PM, Eric Dumazet wrote:
quoted
On Mon, Sep 26, 2022 at 5:25 PM Martin KaFai Lau [off-list ref] wrote:
quoted
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 ?
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
Hello:
This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski [off-list ref]:
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.
[...]
From: Andrei Vagin <hidden> Date: 2023-09-08 21:54:17
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
quoted hunk
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(+)
On Mon, Sep 26, 2022 at 05:25:44PM -0700, Martin KaFai Lau wrote:
quoted
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<---