diff mbox series

[v1,net,1/8] tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-wildcard addresses.

Message ID 20240325181923.48769-2-kuniyu@amazon.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series tcp: Fix bind() regression and more tests. | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 949 this patch: 949
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 956 this patch: 956
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 960 this patch: 960
netdev/checkpatch warning WARNING: line length of 83 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest pending net-next-2024-03-25--21-00 (tests: 0)

Commit Message

Kuniyuki Iwashima March 25, 2024, 6:19 p.m. UTC
Commit 5e07e672412b ("tcp: Use bhash2 for v4-mapped-v6 non-wildcard
address.") introduced bind() regression for v4-mapped-v6 address.

When we bind() the following two addresses on the same port, the 2nd
bind() should succeed but fails now.

  1. [::] w/ IPV6_ONLY
  2. ::ffff:127.0.0.1

After the chagne, v4-mapped-v6 uses bhash2 instead of bhash to
detect conflict faster, but I forgot to add a necessary change.

During the 2nd bind(), inet_bind2_bucket_match_addr_any() returns
the tb2 bucket of [::], and inet_bhash2_conflict() finally calls
inet_bind_conflict(), which returns true, meaning conflict.

  inet_bhash2_addr_any_conflict
  |- inet_bind2_bucket_match_addr_any  <-- return [::] bucket
  `- inet_bhash2_conflict
     `- __inet_bhash2_conflict <-- checks IPV6_ONLY for AF_INET
        |                          but not for v4-mapped-v6 address
        `- inet_bind_conflict  <-- does not check address

inet_bind_conflict() does not check socket addresses because
__inet_bhash2_conflict() is expected to do so.

However, it checks IPV6_V6ONLY attribute only against AF_INET
socket, and not for v4-mapped-v6 address.

As a result, v4-mapped-v6 address conflicts with v6-only wildcard
address.

To avoid that, let's add the missing test to use bhash2 for
v4-mapped-v6 address.

Fixes: 5e07e672412b ("tcp: Use bhash2 for v4-mapped-v6 non-wildcard address.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/inet_connection_sock.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Jakub Kicinski March 25, 2024, 11:56 p.m. UTC | #1
On Mon, 25 Mar 2024 11:19:16 -0700 Kuniyuki Iwashima wrote:
> -	if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
> +	if (ipv6_only_sock(sk2) &&
> +	    (sk->sk_family == AF_INET || ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)))

breaks build for IPV6=n (i.e. TDC):

https://github.com/p4tc-dev/tc-executor/commit/ac16181d7589bdf29c7c3907243e829f6b954570#diff-0042f6af11ac801c4370fb95b8e4f0de734b793c9e23bff936a1bb03c63eb6f0R228
Kuniyuki Iwashima March 26, 2024, 12:01 a.m. UTC | #2
From: Jakub Kicinski <kuba@kernel.org>
Date: Mon, 25 Mar 2024 16:56:33 -0700
> On Mon, 25 Mar 2024 11:19:16 -0700 Kuniyuki Iwashima wrote:
> > -	if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
> > +	if (ipv6_only_sock(sk2) &&
> > +	    (sk->sk_family == AF_INET || ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)))
> 
> breaks build for IPV6=n (i.e. TDC):
> 
> https://github.com/p4tc-dev/tc-executor/commit/ac16181d7589bdf29c7c3907243e829f6b954570#diff-0042f6af11ac801c4370fb95b8e4f0de734b793c9e23bff936a1bb03c63eb6f0R228

Oops, will fix it in v2.

Thanks!
kernel test robot March 26, 2024, 10:41 a.m. UTC | #3
Hi Kuniyuki,

kernel test robot noticed the following build errors:

[auto build test ERROR on net/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Kuniyuki-Iwashima/tcp-Fix-bind-regression-for-v6-only-wildcard-and-v4-mapped-v6-non-wildcard-addresses/20240326-024257
base:   net/main
patch link:    https://lore.kernel.org/r/20240325181923.48769-2-kuniyu%40amazon.com
patch subject: [PATCH v1 net 1/8] tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-wildcard addresses.
config: alpha-defconfig (https://download.01.org/0day-ci/archive/20240326/202403261847.wj7EwLat-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240326/202403261847.wj7EwLat-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403261847.wj7EwLat-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/net/inet_sock.h:22,
                    from include/net/inet_connection_sock.h:21,
                    from net/ipv4/inet_connection_sock.c:15:
   net/ipv4/inet_connection_sock.c: In function '__inet_bhash2_conflict':
>> include/net/sock.h:375:37: error: 'const struct sock_common' has no member named 'skc_v6_rcv_saddr'; did you mean 'skc_rcv_saddr'?
     375 | #define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
         |                                     ^~~~~~~~~~~~~~~~
   net/ipv4/inet_connection_sock.c:207:66: note: in expansion of macro 'sk_v6_rcv_saddr'
     207 |             (sk->sk_family == AF_INET || ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)))
         |                                                                  ^~~~~~~~~~~~~~~


vim +375 include/net/sock.h

4dc6dc7162c08b Eric Dumazet             2009-07-15  354  
68835aba4d9b74 Eric Dumazet             2010-11-30  355  #define sk_dontcopy_begin	__sk_common.skc_dontcopy_begin
68835aba4d9b74 Eric Dumazet             2010-11-30  356  #define sk_dontcopy_end		__sk_common.skc_dontcopy_end
4dc6dc7162c08b Eric Dumazet             2009-07-15  357  #define sk_hash			__sk_common.skc_hash
5080546682bae3 Eric Dumazet             2013-10-02  358  #define sk_portpair		__sk_common.skc_portpair
05dbc7b59481ca Eric Dumazet             2013-10-03  359  #define sk_num			__sk_common.skc_num
05dbc7b59481ca Eric Dumazet             2013-10-03  360  #define sk_dport		__sk_common.skc_dport
5080546682bae3 Eric Dumazet             2013-10-02  361  #define sk_addrpair		__sk_common.skc_addrpair
5080546682bae3 Eric Dumazet             2013-10-02  362  #define sk_daddr		__sk_common.skc_daddr
5080546682bae3 Eric Dumazet             2013-10-02  363  #define sk_rcv_saddr		__sk_common.skc_rcv_saddr
^1da177e4c3f41 Linus Torvalds           2005-04-16  364  #define sk_family		__sk_common.skc_family
^1da177e4c3f41 Linus Torvalds           2005-04-16  365  #define sk_state		__sk_common.skc_state
^1da177e4c3f41 Linus Torvalds           2005-04-16  366  #define sk_reuse		__sk_common.skc_reuse
055dc21a1d1d21 Tom Herbert              2013-01-22  367  #define sk_reuseport		__sk_common.skc_reuseport
9fe516ba3fb29b Eric Dumazet             2014-06-27  368  #define sk_ipv6only		__sk_common.skc_ipv6only
26abe14379f8e2 Eric W. Biederman        2015-05-08  369  #define sk_net_refcnt		__sk_common.skc_net_refcnt
^1da177e4c3f41 Linus Torvalds           2005-04-16  370  #define sk_bound_dev_if		__sk_common.skc_bound_dev_if
^1da177e4c3f41 Linus Torvalds           2005-04-16  371  #define sk_bind_node		__sk_common.skc_bind_node
8feaf0c0a5488b Arnaldo Carvalho de Melo 2005-08-09  372  #define sk_prot			__sk_common.skc_prot
07feaebfcc10cd Eric W. Biederman        2007-09-12  373  #define sk_net			__sk_common.skc_net
efe4208f47f907 Eric Dumazet             2013-10-03  374  #define sk_v6_daddr		__sk_common.skc_v6_daddr
efe4208f47f907 Eric Dumazet             2013-10-03 @375  #define sk_v6_rcv_saddr	__sk_common.skc_v6_rcv_saddr
33cf7c90fe2f97 Eric Dumazet             2015-03-11  376  #define sk_cookie		__sk_common.skc_cookie
70da268b569d32 Eric Dumazet             2015-10-08  377  #define sk_incoming_cpu		__sk_common.skc_incoming_cpu
8e5eb54d303b7c Eric Dumazet             2015-10-08  378  #define sk_flags		__sk_common.skc_flags
ed53d0ab761f5c Eric Dumazet             2015-10-08  379  #define sk_rxhash		__sk_common.skc_rxhash
efe4208f47f907 Eric Dumazet             2013-10-03  380  
5d4cc87414c5d1 Eric Dumazet             2024-02-16  381  	__cacheline_group_begin(sock_write_rx);
43f51df4172955 Eric Dumazet             2021-11-15  382  
9115e8cd2a0c6e Eric Dumazet             2016-12-03  383  	atomic_t		sk_drops;
5d4cc87414c5d1 Eric Dumazet             2024-02-16  384  	__s32			sk_peek_off;
9115e8cd2a0c6e Eric Dumazet             2016-12-03  385  	struct sk_buff_head	sk_error_queue;
b178bb3dfc30d9 Eric Dumazet             2010-11-16  386  	struct sk_buff_head	sk_receive_queue;
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  387  	/*
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  388  	 * The backlog queue is special, it is always used with
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  389  	 * the per-socket spinlock held and requires low latency
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  390  	 * access. Therefore we special case it's implementation.
b178bb3dfc30d9 Eric Dumazet             2010-11-16  391  	 * Note : rmem_alloc is in this structure to fill a hole
b178bb3dfc30d9 Eric Dumazet             2010-11-16  392  	 * on 64bit arches, not because its logically part of
b178bb3dfc30d9 Eric Dumazet             2010-11-16  393  	 * backlog.
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  394  	 */
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  395  	struct {
b178bb3dfc30d9 Eric Dumazet             2010-11-16  396  		atomic_t	rmem_alloc;
b178bb3dfc30d9 Eric Dumazet             2010-11-16  397  		int		len;
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  398  		struct sk_buff	*head;
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  399  		struct sk_buff	*tail;
fa438ccfdfd3f6 Eric Dumazet             2007-03-04  400  	} sk_backlog;
b178bb3dfc30d9 Eric Dumazet             2010-11-16  401  #define sk_rmem_alloc sk_backlog.rmem_alloc
2c8c56e15df3d4 Eric Dumazet             2014-11-11  402  
5d4cc87414c5d1 Eric Dumazet             2024-02-16  403  	__cacheline_group_end(sock_write_rx);
5d4cc87414c5d1 Eric Dumazet             2024-02-16  404  
5d4cc87414c5d1 Eric Dumazet             2024-02-16  405  	__cacheline_group_begin(sock_read_rx);
5d4cc87414c5d1 Eric Dumazet             2024-02-16  406  	/* early demux fields */
5d4cc87414c5d1 Eric Dumazet             2024-02-16  407  	struct dst_entry __rcu	*sk_rx_dst;
5d4cc87414c5d1 Eric Dumazet             2024-02-16  408  	int			sk_rx_dst_ifindex;
5d4cc87414c5d1 Eric Dumazet             2024-02-16  409  	u32			sk_rx_dst_cookie;
5d4cc87414c5d1 Eric Dumazet             2024-02-16  410
kernel test robot March 26, 2024, 11:11 a.m. UTC | #4
Hi Kuniyuki,

kernel test robot noticed the following build errors:

[auto build test ERROR on net/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Kuniyuki-Iwashima/tcp-Fix-bind-regression-for-v6-only-wildcard-and-v4-mapped-v6-non-wildcard-addresses/20240326-024257
base:   net/main
patch link:    https://lore.kernel.org/r/20240325181923.48769-2-kuniyu%40amazon.com
patch subject: [PATCH v1 net 1/8] tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-wildcard addresses.
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20240326/202403261821.5fkObY55-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240326/202403261821.5fkObY55-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403261821.5fkObY55-lkp@intel.com/

All errors (new ones prefixed by >>):

>> net/ipv4/inet_connection_sock.c:207:59: error: no member named 'skc_v6_rcv_saddr' in 'struct sock_common'; did you mean 'skc_rcv_saddr'?
     207 |             (sk->sk_family == AF_INET || ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)))
         |                                                                  ^
   include/net/sock.h:375:37: note: expanded from macro 'sk_v6_rcv_saddr'
     375 | #define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
         |                                     ^
   include/net/sock.h:155:11: note: 'skc_rcv_saddr' declared here
     155 |                         __be32  skc_rcv_saddr;
         |                                 ^
   1 error generated.


vim +207 net/ipv4/inet_connection_sock.c

   201	
   202	static bool __inet_bhash2_conflict(const struct sock *sk, struct sock *sk2,
   203					   kuid_t sk_uid, bool relax,
   204					   bool reuseport_cb_ok, bool reuseport_ok)
   205	{
   206		if (ipv6_only_sock(sk2) &&
 > 207		    (sk->sk_family == AF_INET || ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)))
   208			return false;
   209	
   210		return inet_bind_conflict(sk, sk2, sk_uid, relax,
   211					  reuseport_cb_ok, reuseport_ok);
   212	}
   213
diff mbox series

Patch

diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 7d8090f109ef..612aa1d2eff7 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -203,7 +203,8 @@  static bool __inet_bhash2_conflict(const struct sock *sk, struct sock *sk2,
 				   kuid_t sk_uid, bool relax,
 				   bool reuseport_cb_ok, bool reuseport_ok)
 {
-	if (sk->sk_family == AF_INET && ipv6_only_sock(sk2))
+	if (ipv6_only_sock(sk2) &&
+	    (sk->sk_family == AF_INET || ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)))
 		return false;
 
 	return inet_bind_conflict(sk, sk2, sk_uid, relax,