]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
144940bdc9cef71b104580ad7f5308f1b6ccd113
[thirdparty/kernel/stable-queue.git] /
1 From ea111449501ea32bf6da82750de860243691efc7 Mon Sep 17 00:00:00 2001
2 From: Kuniyuki Iwashima <kuniyu@amazon.com>
3 Date: Tue, 26 Mar 2024 13:42:44 -0700
4 Subject: tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-wildcard addresses.
5
6 From: Kuniyuki Iwashima <kuniyu@amazon.com>
7
8 commit ea111449501ea32bf6da82750de860243691efc7 upstream.
9
10 Commit 5e07e672412b ("tcp: Use bhash2 for v4-mapped-v6 non-wildcard
11 address.") introduced bind() regression for v4-mapped-v6 address.
12
13 When we bind() the following two addresses on the same port, the 2nd
14 bind() should succeed but fails now.
15
16 1. [::] w/ IPV6_ONLY
17 2. ::ffff:127.0.0.1
18
19 After the chagne, v4-mapped-v6 uses bhash2 instead of bhash to
20 detect conflict faster, but I forgot to add a necessary change.
21
22 During the 2nd bind(), inet_bind2_bucket_match_addr_any() returns
23 the tb2 bucket of [::], and inet_bhash2_conflict() finally calls
24 inet_bind_conflict(), which returns true, meaning conflict.
25
26 inet_bhash2_addr_any_conflict
27 |- inet_bind2_bucket_match_addr_any <-- return [::] bucket
28 `- inet_bhash2_conflict
29 `- __inet_bhash2_conflict <-- checks IPV6_ONLY for AF_INET
30 | but not for v4-mapped-v6 address
31 `- inet_bind_conflict <-- does not check address
32
33 inet_bind_conflict() does not check socket addresses because
34 __inet_bhash2_conflict() is expected to do so.
35
36 However, it checks IPV6_V6ONLY attribute only against AF_INET
37 socket, and not for v4-mapped-v6 address.
38
39 As a result, v4-mapped-v6 address conflicts with v6-only wildcard
40 address.
41
42 To avoid that, let's add the missing test to use bhash2 for
43 v4-mapped-v6 address.
44
45 Fixes: 5e07e672412b ("tcp: Use bhash2 for v4-mapped-v6 non-wildcard address.")
46 Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
47 Link: https://lore.kernel.org/r/20240326204251.51301-2-kuniyu@amazon.com
48 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
49 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
50 ---
51 net/ipv4/inet_connection_sock.c | 11 +++++++++--
52 1 file changed, 9 insertions(+), 2 deletions(-)
53
54 diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
55 index c038e28e2f1e..4184d45f890c 100644
56 --- a/net/ipv4/inet_connection_sock.c
57 +++ b/net/ipv4/inet_connection_sock.c
58 @@ -203,8 +203,15 @@ static bool __inet_bhash2_conflict(const struct sock *sk, struct sock *sk2,
59 kuid_t sk_uid, bool relax,
60 bool reuseport_cb_ok, bool reuseport_ok)
61 {
62 - if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
63 - return false;
64 + if (ipv6_only_sock(sk2)) {
65 + if (sk->sk_family == AF_INET)
66 + return false;
67 +
68 +#if IS_ENABLED(CONFIG_IPV6)
69 + if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
70 + return false;
71 +#endif
72 + }
73
74 return inet_bind_conflict(sk, sk2, sk_uid, relax,
75 reuseport_cb_ok, reuseport_ok);
76 --
77 2.44.0
78