All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@google.com>
To: norbert@doyensec.com
Cc: daniel@iogearbox.net, davem@davemloft.net, edumazet@kernel.org,
	 horms@kernel.org, kuba@kernel.org, kuniyu@google.com,
	 linux-kernel@vger.kernel.org, martin.lau@linux.dev,
	netdev@vger.kernel.org,  pabeni@redhat.com, willemb@google.com
Subject: Re: [PATCH net] soreuseport: Fix use-after-free when a socket is added to socks[] twice
Date: Mon, 28 Sep 2026 17:45:04 +0000	[thread overview]
Message-ID: <20260928174546.4022833-1-kuniyu@google.com> (raw)
In-Reply-To: <6E4F8645-9453-45F1-B068-52E1B14E8B0C@doyensec.com>

From: Norbert Szetei <norbert@doyensec.com>
Date: Mon, 28 Sep 2026 19:22:38 +0200
> reuseport_stop_listen_sock() moves a shutdown()ed listener from the
> listening section of reuse->socks[] to the closed section: it removes the
> socket with __reuseport_detach_sock() and adds it back with
> __reuseport_add_closed_sock(). The return value of the removal is
> discarded and the add runs unconditionally.
> 
> The socket need not be in the listening section. inet_unhash() calls
> reuseport_stop_listen_sock() for a listener whenever sk->sk_reuseport_cb
> is set, but inet_hash() enters the reuseport path only when
> sk->sk_reuseport is set, and SO_REUSEPORT can be cleared in any state.

This has long been a known problem, and I think it's time
to fix it instead of working around it:

diff --git a/net/core/sock.c b/net/core/sock.c
index 2948dffcc3e1..a33cdf99368d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1324,6 +1324,8 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
 	case SO_REUSEPORT:
 		if (valbool && !sk_is_inet(sk))
 			ret = -EOPNOTSUPP;
+		else if (!valbool && rcu_access_pointer(sk->sk_reuseport_cb))
+			ret = -EBUSY;
 		else
 			sk->sk_reuseport = valbool;
 		break;


> Clearing it between shutdown() and listen() makes that listen() skip
> reuseport_add_sock(), and with it reuseport_resurrect(), so the socket is
> hashed as a listener while it is still in the closed section. On the next
> shutdown() __reuseport_detach_sock() does not find it in the listening
> section, returns false, and __reuseport_add_closed_sock() adds a second
> copy of it to socks[].
> 
> sk_destruct() calls reuseport_detach_sock(), which removes one of the two
> entries. reuseport_grow() then dereferences the other one, because its
> loop runs over every slot up to reuse->max_socks:
> 
>   BUG: KASAN: slab-use-after-free in reuseport_grow (net/core/sock_reuseport.c:291)
>   Write of size 8 at addr ffff888132359988 by task poc/621
> 
>    reuseport_grow (net/core/sock_reuseport.c:291)
>    reuseport_add_sock (net/core/sock_reuseport.c:350)
>    inet_hash (net/ipv4/inet_hashtables.c:810)
>    inet_csk_listen_start (net/ipv4/inet_connection_sock.c:1359)
>    __inet_listen_sk (net/ipv4/af_inet.c:225)
>    inet_listen (net/ipv4/af_inet.c:247)
>    __sys_listen (net/socket.c:2014)
> 
>   Allocated by task 621:
>    sk_prot_alloc (net/core/sock.c:2246)
>    sk_alloc (net/core/sock.c:2308)
>    inet_create (net/ipv4/af_inet.c:333)
> 
>   Freed by task 0:
>    slab_free_after_rcu_debug (mm/slub.c:6570)
>    rcu_core (kernel/rcu/tree.c:2919)
> 
>   The buggy address is located 904 bytes inside of
>    freed 2624-byte region [ffff888132359600, ffff88813235a040)
> 
> Only move the socket to the closed section when __reuseport_detach_sock()
> reports that it was removed from the listening section.
> 
> Fixes: 333bb73f620e ("tcp: Keep TCP_CLOSE sockets in the reuseport group.")
> Assisted-by: LLM
> Signed-off-by: Norbert Szetei <norbert@doyensec.com>
> ---
>  net/core/sock_reuseport.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
> index 29948cb44b7d..031b641be317 100644
> --- a/net/core/sock_reuseport.c
> +++ b/net/core/sock_reuseport.c
> @@ -479,8 +479,8 @@ void reuseport_stop_listen_sock(struct sock *sk)
>  			 */
>  			bpf_sk_reuseport_detach(sk);
>  
> -			__reuseport_detach_sock(sk, reuse);
> -			__reuseport_add_closed_sock(sk, reuse);
> +			if (__reuseport_detach_sock(sk, reuse))
> +				__reuseport_add_closed_sock(sk, reuse);
>  
>  			spin_unlock_bh(&reuseport_lock);
>  			return;
> -- 
> 2.55.0
> 

  reply	other threads:[~2026-09-28 17:45 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28 17:22 [PATCH net] soreuseport: Fix use-after-free when a socket is added to socks[] twice Norbert Szetei
2026-09-28 17:45 ` Kuniyuki Iwashima [this message]
2026-09-29 15:30   ` Norbert Szetei
2026-09-29 18:31     ` Kuniyuki Iwashima
2026-09-30 17:24 ` netdev-bot+sashiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260928174546.4022833-1-kuniyu@google.com \
    --to=kuniyu@google.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=norbert@doyensec.com \
    --cc=pabeni@redhat.com \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.