Linux bluetooth development
 help / color / mirror / Atom feed
From: Pauli Virtanen <pav@iki.fi>
To: Zihan Xi <zihanx@nebusec.ai>, linux-bluetooth@vger.kernel.org
Cc: Marcel Holtmann <marcel@holtmann.org>,
	Luiz Augusto von Dentz	 <luiz.dentz@gmail.com>,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH v2 1/1] Bluetooth: Fix parent socket UAF in accept queues
Date: Thu, 03 Sep 2026 18:11:29 +0300	[thread overview]
Message-ID: <3674f5d34d731403bfa0e680c9e5718237612315.camel@iki.fi> (raw)
In-Reply-To: <34824eaea68a895a3fe9ed5337248eca1d81f74f.1788259244.git.zihanx@nebusec.ai>

Hi,

to, 2026-09-03 kello 11:11 +0000, Zihan Xi kirjoitti:
> Bluetooth children queued on a listening socket store the listener in
> bt_sk(sk)->parent, but the accept queue did not hold a reference on
> that parent socket.  The child side can later fetch that pointer and
> unlink itself from the accept queue while still needing to notify the
> listener, for example from L2CAP, ISO or RFCOMM teardown/state-change
> callbacks.

Please revalidate the KASAN crash on current bluetooth-next/master,
there have been related fixes since v1 of the patch and the v7.2-rc6
shown in the KASAN crash in the cover letter.

With commit d4bfa78fd679 ("Bluetooth: L2CAP: reject accept queue add
unless BT_LISTEN") in v7.3-rc1 cherry-picked on v7.2-rc6 the POC no
longer reproduces for me.

***

The design intent AFAICS is that the accept queue of the parent socket
shall be empty when the parent socket is freed.

Otherwise, the child sockets in accept queue would leak.

There must then be parent->sk_state == BT_LISTEN check before
bt_accept_enqueue() and some were missing in v7.2-rc6.

bt_sk(sk)->parent read/write is guarded by lock_sock(sk), and it is set
to NULL when removed from accept queue.

Dangling bt_sk(sk)->parent should then not occur.

If bt_sk(sk)->parent != NULL is observed under lock_sock(sk), the
parent socket is valid during that critical section.

The sock_hold/put(parent) in this patch are in lock_sock(sk) critical
sections, so should be no-ops.

The accept queue items owning reference to parent also should be no-
ops.

> If the listener is closed concurrently, removing the child from the
> accept queue can drop the last listener reference before those
> callbacks call parent->sk_data_ready(parent), leaving a stale parent
> pointer and a use-after-free.
> 
> Take a reference on the parent when a child is queued and drop it when
> the child is unlinked.  Since unlinking now drops the accept-queue
> parent reference, take a temporary parent reference in the callbacks
> that continue to notify the parent after bt_accept_unlink().
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Reported-by: Vega <vega@nebusec.ai>
> Assisted-by: Codex:gpt-5.4
> Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
> ---
> changes in v2:
>   - rebase onto current bluetooth-next
>   - refresh trailers to the current submission template
>   - retarget author identity to Zihan Xi <zihanx@nebusec.ai>
>   - v1 Link: https://lore.kernel.org/all/65767989c644f8adf52f35334f4034c66f47881f.1784383243.git.xizh2024@lzu.edu.cn/
> 
>  net/bluetooth/af_bluetooth.c | 2 ++
>  net/bluetooth/iso.c          | 2 ++
>  net/bluetooth/l2cap_sock.c   | 2 ++
>  net/bluetooth/rfcomm/sock.c  | 2 ++
>  4 files changed, 8 insertions(+)
> 
> diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
> index 411d66f24393..61a232378e6c 100644
> --- a/net/bluetooth/af_bluetooth.c
> +++ b/net/bluetooth/af_bluetooth.c
> @@ -218,6 +218,7 @@ void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
>  	BT_DBG("parent %p, sk %p", parent, sk);
>  
>  	sock_hold(sk);
> +	sock_hold(parent);
>  
>  	if (bh)
>  		bh_lock_sock_nested(sk);
> @@ -266,6 +267,7 @@ void bt_accept_unlink(struct sock *sk)
>  	spin_unlock_bh(&bt_sk(parent)->accept_q_lock);
>  	bt_sk(sk)->parent = NULL;
>  	sock_put(sk);
> +	sock_put(parent);
>  }
>  EXPORT_SYMBOL(bt_accept_unlink);
>  
> diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
> index 75bfd5938b2e..e709292aa112 100644
> --- a/net/bluetooth/iso.c
> +++ b/net/bluetooth/iso.c
> @@ -286,8 +286,10 @@ static void iso_chan_del(struct sock *sk, int err)
>  
>  	parent = bt_sk(sk)->parent;
>  	if (parent) {
> +		sock_hold(parent);
>  		bt_accept_unlink(sk);
>  		parent->sk_data_ready(parent);
> +		sock_put(parent);
>  	} else {
>  		sk->sk_state_change(sk);
>  	}
> diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
> index b553b6356af8..3720ab2e39ed 100644
> --- a/net/bluetooth/l2cap_sock.c
> +++ b/net/bluetooth/l2cap_sock.c
> @@ -1748,8 +1748,10 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
>  		sk->sk_err = err;
>  
>  		if (parent) {
> +			sock_hold(parent);
>  			bt_accept_unlink(sk);
>  			parent->sk_data_ready(parent);
> +			sock_put(parent);
>  		} else {
>  			sk->sk_state_change(sk);
>  		}
> diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
> index 958081adb9b5..a16daa68ecb8 100644
> --- a/net/bluetooth/rfcomm/sock.c
> +++ b/net/bluetooth/rfcomm/sock.c
> @@ -78,11 +78,13 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
>  
>  	parent = bt_sk(sk)->parent;
>  	if (parent) {
> +		sock_hold(parent);
>  		if (d->state == BT_CLOSED) {
>  			sock_set_flag(sk, SOCK_ZAPPED);
>  			bt_accept_unlink(sk);
>  		}
>  		parent->sk_data_ready(parent);
> +		sock_put(parent);
>  	} else {
>  		if (d->state == BT_CONNECTED)
>  			rfcomm_session_getaddr(d->session,

-- 
Pauli Virtanen

  reply	other threads:[~2026-09-03 15:11 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-03 11:11 [PATCH v2 0/1] Bluetooth: Fix parent socket UAF in accept queues Zihan Xi
2026-09-03 11:11 ` [PATCH v2 1/1] " Zihan Xi
2026-09-03 15:11   ` Pauli Virtanen [this message]
2026-09-04  5:42     ` zihan xi
2026-09-03 15:22   ` bluez.test.bot

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=3674f5d34d731403bfa0e680c9e5718237612315.camel@iki.fi \
    --to=pav@iki.fi \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    --cc=stable@vger.kernel.org \
    --cc=zihanx@nebusec.ai \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox