lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Tue, 18 Jun 2024 12:54:53 +0200
From: Paolo Abeni <pabeni@...hat.com>
To: Kuniyuki Iwashima <kuniyu@...zon.com>, Kent Overstreet
	 <kent.overstreet@...ux.dev>
Cc: "David S. Miller" <davem@...emloft.net>, Eric Dumazet
 <edumazet@...gle.com>,  Jakub Kicinski <kuba@...nel.org>, Kuniyuki Iwashima
 <kuni1840@...il.com>,  netdev@...r.kernel.org
Subject: Re: [PATCH v3 net-next 04/11] af_unix: Define locking order for
 U_LOCK_SECOND in unix_stream_connect().

On Fri, 2024-06-14 at 13:07 -0700, Kuniyuki Iwashima wrote:
> While a SOCK_(STREAM|SEQPACKET) socket connect()s to another, we hold
> two locks of them by unix_state_lock() and unix_state_lock_nested() in
> unix_stream_connect().
> 
> Before unix_state_lock_nested(), the following is guaranteed by checking
> sk->sk_state:
> 
>   1. The first socket is TCP_LISTEN
>   2. The second socket is not the first one
>   3. Simultaneous connect() must fail
> 
> So, the client state can be TCP_CLOSE or TCP_LISTEN or TCP_ESTABLISHED.
> 
> Let's define the expected states as unix_state_lock_cmp_fn() instead of
> using unix_state_lock_nested().
> 
> Note that 2. is detected by debug_spin_lock_before() and 3. cannot be
> expressed as lock_cmp_fn.
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@...zon.com>
> ---
>  include/net/af_unix.h |  1 -
>  net/unix/af_unix.c    | 26 +++++++++++++++++++++++++-
>  2 files changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/include/net/af_unix.h b/include/net/af_unix.h
> index b6eedf7650da..fd813ad73ab8 100644
> --- a/include/net/af_unix.h
> +++ b/include/net/af_unix.h
> @@ -98,7 +98,6 @@ struct unix_sock {
>  #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
>  enum unix_socket_lock_class {
>  	U_LOCK_NORMAL,
> -	U_LOCK_SECOND,	/* for double locking, see unix_state_double_lock(). */
>  	U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */
>  	U_LOCK_GC_LISTENER, /* used for listening socket while determining gc
>  			     * candidates to close a small race window.
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 88f2c5d039c4..5d2728e33f3f 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -143,6 +143,30 @@ static int unix_state_lock_cmp_fn(const struct lockdep_map *_a,
>  	a = container_of(_a, struct unix_sock, lock.dep_map);
>  	b = container_of(_b, struct unix_sock, lock.dep_map);
>  
> +	if (a->sk.sk_state == TCP_LISTEN) {
> +		/* unix_stream_connect(): Before the 2nd unix_state_lock(),
> +		 *
> +		 *   1. a is TCP_LISTEN.
> +		 *   2. b is not a.
> +		 *   3. concurrent connect(b -> a) must fail.
> +		 *
> +		 * Except for 2. & 3., the b's state can be any possible
> +		 * value due to concurrent connect() or listen().
> +		 *
> +		 * 2. is detected in debug_spin_lock_before(), and 3. cannot
> +		 * be expressed as lock_cmp_fn.
> +		 */
> +		switch (b->sk.sk_state) {
> +		case TCP_CLOSE:
> +		case TCP_ESTABLISHED:
> +		case TCP_LISTEN:
> +			return -1;
> +		default:
> +			/* Invalid case. */
> +			return 0;
> +		}

I'm sorry for missing this before, but I'm wondering if we need to
enforce even this case to be symmetric? that is, explicitly check for b
state == TCP_LISTEN, ...

Kent, WDYT?

Thanks!

Paolo


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ