* [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes
@ 2026-07-20 18:30 Pauli Virtanen
2026-07-20 19:37 ` Luiz Augusto von Dentz
2026-07-20 20:30 ` [v2] " bluez.test.bot
0 siblings, 2 replies; 5+ messages in thread
From: Pauli Virtanen @ 2026-07-20 18:30 UTC (permalink / raw)
To: linux-bluetooth
Cc: Pauli Virtanen, marcel, luiz.dentz, iulia.tanasescu, linux-kernel
iso_sock_disconn() aims to disconnect the hcon by dropping it, which
triggers iso_conn_del() once the HCI operation completes, requiring
valid hcon->iso_data to do socket cleanup. iso_sock_disconn() sets
conn->hcon = NULL to avoid a second drop, but also preventing clearing
hcon->iso_data on socket release. Closing the socket before
iso_conn_del() runs then results to UAF.
Fix by using a separate flag to track the hcon drop status, instead of
clearing conn->hcon.
Log: (BlueZ iso-tester ISO Connect Close - Success)
BUG: KASAN: slab-use-after-free in iso_conn_hold_unless_zero
...
iso_conn_hold_unless_zero (net/bluetooth/iso.c:138)
iso_conn_del (net/bluetooth/iso.c:270)
hci_conn_failed (net/bluetooth/hci_conn.c:1408)
hci_abort_conn_sync (net/bluetooth/hci_sync.c:5817)
Allocated by task 34:
iso_conn_add (net/bluetooth/iso.c:216)
iso_connect_cis (net/bluetooth/iso.c:507)
iso_sock_connect (net/bluetooth/iso.c:1211)
__sys_connect (net/socket.c:2148)
Freed by task 34:
iso_chan_del (net/bluetooth/iso.c:248)
iso_sock_close (net/bluetooth/iso.c:885)
iso_sock_release (net/bluetooth/iso.c:2022)
sock_close (net/socket.c:722)
Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
net/bluetooth/iso.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 2e95a153912c..6abc2b1f59bc 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -30,6 +30,7 @@ struct iso_conn {
/* @lock: spinlock protecting changes to iso_conn fields */
spinlock_t lock;
struct sock *sk;
+ bool hcon_dropped;
struct delayed_work timeout_work;
@@ -107,7 +108,8 @@ static void iso_conn_free(struct kref *ref)
if (conn->hcon) {
conn->hcon->iso_data = NULL;
- hci_conn_drop(conn->hcon);
+ if (!conn->hcon_dropped)
+ hci_conn_drop(conn->hcon);
}
/* Ensure no more work items will run since hci_conn has been dropped */
@@ -306,6 +308,7 @@ static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
iso_pi(sk)->conn = conn;
conn->sk = sk;
+ conn->hcon_dropped = false;
if (parent)
bt_accept_enqueue(parent, sk, true);
@@ -836,8 +839,10 @@ static void iso_sock_disconn(struct sock *sk)
sk->sk_state = BT_DISCONN;
iso_conn_lock(iso_pi(sk)->conn);
- hci_conn_drop(iso_pi(sk)->conn->hcon);
- iso_pi(sk)->conn->hcon = NULL;
+ if (!iso_pi(sk)->conn->hcon_dropped) {
+ iso_pi(sk)->conn->hcon_dropped = true;
+ hci_conn_drop(iso_pi(sk)->conn->hcon);
+ }
iso_conn_unlock(iso_pi(sk)->conn);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes
2026-07-20 18:30 [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes Pauli Virtanen
@ 2026-07-20 19:37 ` Luiz Augusto von Dentz
2026-07-20 20:08 ` Pauli Virtanen
2026-07-20 20:30 ` [v2] " bluez.test.bot
1 sibling, 1 reply; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2026-07-20 19:37 UTC (permalink / raw)
To: Pauli Virtanen; +Cc: linux-bluetooth, marcel, iulia.tanasescu, linux-kernel
Hi Pauli,
On Mon, Jul 20, 2026 at 2:30 PM Pauli Virtanen <pav@iki.fi> wrote:
>
> iso_sock_disconn() aims to disconnect the hcon by dropping it, which
> triggers iso_conn_del() once the HCI operation completes, requiring
> valid hcon->iso_data to do socket cleanup. iso_sock_disconn() sets
> conn->hcon = NULL to avoid a second drop, but also preventing clearing
> hcon->iso_data on socket release. Closing the socket before
> iso_conn_del() runs then results to UAF.
>
> Fix by using a separate flag to track the hcon drop status, instead of
> clearing conn->hcon.
>
> Log: (BlueZ iso-tester ISO Connect Close - Success)
> BUG: KASAN: slab-use-after-free in iso_conn_hold_unless_zero
> ...
> iso_conn_hold_unless_zero (net/bluetooth/iso.c:138)
> iso_conn_del (net/bluetooth/iso.c:270)
> hci_conn_failed (net/bluetooth/hci_conn.c:1408)
> hci_abort_conn_sync (net/bluetooth/hci_sync.c:5817)
>
> Allocated by task 34:
> iso_conn_add (net/bluetooth/iso.c:216)
> iso_connect_cis (net/bluetooth/iso.c:507)
> iso_sock_connect (net/bluetooth/iso.c:1211)
> __sys_connect (net/socket.c:2148)
>
> Freed by task 34:
> iso_chan_del (net/bluetooth/iso.c:248)
> iso_sock_close (net/bluetooth/iso.c:885)
> iso_sock_release (net/bluetooth/iso.c:2022)
> sock_close (net/socket.c:722)
>
> Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
> Signed-off-by: Pauli Virtanen <pav@iki.fi>
> ---
> net/bluetooth/iso.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
> index 2e95a153912c..6abc2b1f59bc 100644
> --- a/net/bluetooth/iso.c
> +++ b/net/bluetooth/iso.c
> @@ -30,6 +30,7 @@ struct iso_conn {
> /* @lock: spinlock protecting changes to iso_conn fields */
> spinlock_t lock;
> struct sock *sk;
> + bool hcon_dropped;
It might be safer to add a flag or something so we can perform atomic
operations to check if dropping is necessary.
> struct delayed_work timeout_work;
>
> @@ -107,7 +108,8 @@ static void iso_conn_free(struct kref *ref)
>
> if (conn->hcon) {
> conn->hcon->iso_data = NULL;
> - hci_conn_drop(conn->hcon);
> + if (!conn->hcon_dropped)
> + hci_conn_drop(conn->hcon);
> }
>
> /* Ensure no more work items will run since hci_conn has been dropped */
> @@ -306,6 +308,7 @@ static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
>
> iso_pi(sk)->conn = conn;
> conn->sk = sk;
> + conn->hcon_dropped = false;
>
> if (parent)
> bt_accept_enqueue(parent, sk, true);
> @@ -836,8 +839,10 @@ static void iso_sock_disconn(struct sock *sk)
>
> sk->sk_state = BT_DISCONN;
> iso_conn_lock(iso_pi(sk)->conn);
> - hci_conn_drop(iso_pi(sk)->conn->hcon);
> - iso_pi(sk)->conn->hcon = NULL;
> + if (!iso_pi(sk)->conn->hcon_dropped) {
> + iso_pi(sk)->conn->hcon_dropped = true;
> + hci_conn_drop(iso_pi(sk)->conn->hcon);
> + }
> iso_conn_unlock(iso_pi(sk)->conn);
> }
>
> --
> 2.55.0
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes
2026-07-20 19:37 ` Luiz Augusto von Dentz
@ 2026-07-20 20:08 ` Pauli Virtanen
2026-07-20 20:14 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 5+ messages in thread
From: Pauli Virtanen @ 2026-07-20 20:08 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: linux-bluetooth, marcel, iulia.tanasescu, linux-kernel
Hi Luiz,
ma, 2026-07-20 kello 15:37 -0400, Luiz Augusto von Dentz kirjoitti:
> Hi Pauli,
>
> On Mon, Jul 20, 2026 at 2:30 PM Pauli Virtanen <pav@iki.fi> wrote:
> >
> > iso_sock_disconn() aims to disconnect the hcon by dropping it, which
> > triggers iso_conn_del() once the HCI operation completes, requiring
> > valid hcon->iso_data to do socket cleanup. iso_sock_disconn() sets
> > conn->hcon = NULL to avoid a second drop, but also preventing clearing
> > hcon->iso_data on socket release. Closing the socket before
> > iso_conn_del() runs then results to UAF.
> >
> > Fix by using a separate flag to track the hcon drop status, instead of
> > clearing conn->hcon.
> >
> > Log: (BlueZ iso-tester ISO Connect Close - Success)
> > BUG: KASAN: slab-use-after-free in iso_conn_hold_unless_zero
> > ...
> > iso_conn_hold_unless_zero (net/bluetooth/iso.c:138)
> > iso_conn_del (net/bluetooth/iso.c:270)
> > hci_conn_failed (net/bluetooth/hci_conn.c:1408)
> > hci_abort_conn_sync (net/bluetooth/hci_sync.c:5817)
> >
> > Allocated by task 34:
> > iso_conn_add (net/bluetooth/iso.c:216)
> > iso_connect_cis (net/bluetooth/iso.c:507)
> > iso_sock_connect (net/bluetooth/iso.c:1211)
> > __sys_connect (net/socket.c:2148)
> >
> > Freed by task 34:
> > iso_chan_del (net/bluetooth/iso.c:248)
> > iso_sock_close (net/bluetooth/iso.c:885)
> > iso_sock_release (net/bluetooth/iso.c:2022)
> > sock_close (net/socket.c:722)
> >
> > Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
> > Signed-off-by: Pauli Virtanen <pav@iki.fi>
> > ---
> > net/bluetooth/iso.c | 11 ++++++++---
> > 1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
> > index 2e95a153912c..6abc2b1f59bc 100644
> > --- a/net/bluetooth/iso.c
> > +++ b/net/bluetooth/iso.c
> > @@ -30,6 +30,7 @@ struct iso_conn {
> > /* @lock: spinlock protecting changes to iso_conn fields */
> > spinlock_t lock;
> > struct sock *sk;
> > + bool hcon_dropped;
>
> It might be safer to add a flag or something so we can perform atomic
> operations to check if dropping is necessary.
It is serialized by iso_conn::lock + kref, so AFAICS it is safe. I can
change it to test_and_set_bit() regardless if still preferable.
The lock is not taken in iso_conn_free() --- at that point nobody is
holding a reference so there should be no concurrent modification, so
AFAIK it is taken care of by the refcount memory ordering (see comment
in include/linux/refcount.h), otherwise conn->hcon etc would also be
wrong.
The
comment https://sashiko.dev/#/patchset/4d96c545ad1a2fed02440a3478905853286aa0c7.1784571683.git.pav%40iki.fi
on Sashiko seems to miss that iso_connect_cfm / iso_disconn_cfm ->
iso_conn_del() are called before hci_conn is deleted, and should make
sure there's no dangling reference to the hci_conn. It would be same as
for remote disconnect. Maybe the prompts it uses in
https://github.com/masoncl/review-prompts/blob/main/kernel/subsystem/bluetooth.md
could be improved vs hci_conn and socket life cycles.
> > struct delayed_work timeout_work;
> >
> > @@ -107,7 +108,8 @@ static void iso_conn_free(struct kref *ref)
> >
> > if (conn->hcon) {
> > conn->hcon->iso_data = NULL;
> > - hci_conn_drop(conn->hcon);
> > + if (!conn->hcon_dropped)
> > + hci_conn_drop(conn->hcon);
> > }
> >
> > /* Ensure no more work items will run since hci_conn has been dropped */
> > @@ -306,6 +308,7 @@ static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
> >
> > iso_pi(sk)->conn = conn;
> > conn->sk = sk;
> > + conn->hcon_dropped = false;
> >
> > if (parent)
> > bt_accept_enqueue(parent, sk, true);
> > @@ -836,8 +839,10 @@ static void iso_sock_disconn(struct sock *sk)
> >
> > sk->sk_state = BT_DISCONN;
> > iso_conn_lock(iso_pi(sk)->conn);
> > - hci_conn_drop(iso_pi(sk)->conn->hcon);
> > - iso_pi(sk)->conn->hcon = NULL;
> > + if (!iso_pi(sk)->conn->hcon_dropped) {
> > + iso_pi(sk)->conn->hcon_dropped = true;
> > + hci_conn_drop(iso_pi(sk)->conn->hcon);
> > + }
> > iso_conn_unlock(iso_pi(sk)->conn);
> > }
> >
> > --
> > 2.55.0
> >
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes
2026-07-20 20:08 ` Pauli Virtanen
@ 2026-07-20 20:14 ` Luiz Augusto von Dentz
0 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2026-07-20 20:14 UTC (permalink / raw)
To: Pauli Virtanen; +Cc: linux-bluetooth, marcel, iulia.tanasescu, linux-kernel
Hi Pauli,
On Mon, Jul 20, 2026 at 4:08 PM Pauli Virtanen <pauli.virtanen@iki.fi> wrote:
>
> Hi Luiz,
>
> ma, 2026-07-20 kello 15:37 -0400, Luiz Augusto von Dentz kirjoitti:
> > Hi Pauli,
> >
> > On Mon, Jul 20, 2026 at 2:30 PM Pauli Virtanen <pav@iki.fi> wrote:
> > >
> > > iso_sock_disconn() aims to disconnect the hcon by dropping it, which
> > > triggers iso_conn_del() once the HCI operation completes, requiring
> > > valid hcon->iso_data to do socket cleanup. iso_sock_disconn() sets
> > > conn->hcon = NULL to avoid a second drop, but also preventing clearing
> > > hcon->iso_data on socket release. Closing the socket before
> > > iso_conn_del() runs then results to UAF.
> > >
> > > Fix by using a separate flag to track the hcon drop status, instead of
> > > clearing conn->hcon.
> > >
> > > Log: (BlueZ iso-tester ISO Connect Close - Success)
> > > BUG: KASAN: slab-use-after-free in iso_conn_hold_unless_zero
> > > ...
> > > iso_conn_hold_unless_zero (net/bluetooth/iso.c:138)
> > > iso_conn_del (net/bluetooth/iso.c:270)
> > > hci_conn_failed (net/bluetooth/hci_conn.c:1408)
> > > hci_abort_conn_sync (net/bluetooth/hci_sync.c:5817)
> > >
> > > Allocated by task 34:
> > > iso_conn_add (net/bluetooth/iso.c:216)
> > > iso_connect_cis (net/bluetooth/iso.c:507)
> > > iso_sock_connect (net/bluetooth/iso.c:1211)
> > > __sys_connect (net/socket.c:2148)
> > >
> > > Freed by task 34:
> > > iso_chan_del (net/bluetooth/iso.c:248)
> > > iso_sock_close (net/bluetooth/iso.c:885)
> > > iso_sock_release (net/bluetooth/iso.c:2022)
> > > sock_close (net/socket.c:722)
> > >
> > > Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
> > > Signed-off-by: Pauli Virtanen <pav@iki.fi>
> > > ---
> > > net/bluetooth/iso.c | 11 ++++++++---
> > > 1 file changed, 8 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
> > > index 2e95a153912c..6abc2b1f59bc 100644
> > > --- a/net/bluetooth/iso.c
> > > +++ b/net/bluetooth/iso.c
> > > @@ -30,6 +30,7 @@ struct iso_conn {
> > > /* @lock: spinlock protecting changes to iso_conn fields */
> > > spinlock_t lock;
> > > struct sock *sk;
> > > + bool hcon_dropped;
> >
> > It might be safer to add a flag or something so we can perform atomic
> > operations to check if dropping is necessary.
>
> It is serialized by iso_conn::lock + kref, so AFAICS it is safe. I can
> change it to test_and_set_bit() regardless if still preferable.
I'm afraid in today's world that is sort of required; otherwise,
someone using an AI model might miss the serialization and send
patches to 'fix' it anyway, just creating more work for us to review.
> The lock is not taken in iso_conn_free() --- at that point nobody is
> holding a reference so there should be no concurrent modification, so
> AFAIK it is taken care of by the refcount memory ordering (see comment
> in include/linux/refcount.h), otherwise conn->hcon etc would also be
> wrong.
>
> The
> comment https://sashiko.dev/#/patchset/4d96c545ad1a2fed02440a3478905853286aa0c7.1784571683.git.pav%40iki.fi
> on Sashiko seems to miss that iso_connect_cfm / iso_disconn_cfm ->
> iso_conn_del() are called before hci_conn is deleted, and should make
> sure there's no dangling reference to the hci_conn. It would be same as
> for remote disconnect. Maybe the prompts it uses in
> https://github.com/masoncl/review-prompts/blob/main/kernel/subsystem/bluetooth.md
> could be improved vs hci_conn and socket life cycles.
>
> > > struct delayed_work timeout_work;
> > >
> > > @@ -107,7 +108,8 @@ static void iso_conn_free(struct kref *ref)
> > >
> > > if (conn->hcon) {
> > > conn->hcon->iso_data = NULL;
> > > - hci_conn_drop(conn->hcon);
> > > + if (!conn->hcon_dropped)
> > > + hci_conn_drop(conn->hcon);
> > > }
> > >
> > > /* Ensure no more work items will run since hci_conn has been dropped */
> > > @@ -306,6 +308,7 @@ static int __iso_chan_add(struct iso_conn *conn, struct sock *sk,
> > >
> > > iso_pi(sk)->conn = conn;
> > > conn->sk = sk;
> > > + conn->hcon_dropped = false;
> > >
> > > if (parent)
> > > bt_accept_enqueue(parent, sk, true);
> > > @@ -836,8 +839,10 @@ static void iso_sock_disconn(struct sock *sk)
> > >
> > > sk->sk_state = BT_DISCONN;
> > > iso_conn_lock(iso_pi(sk)->conn);
> > > - hci_conn_drop(iso_pi(sk)->conn->hcon);
> > > - iso_pi(sk)->conn->hcon = NULL;
> > > + if (!iso_pi(sk)->conn->hcon_dropped) {
> > > + iso_pi(sk)->conn->hcon_dropped = true;
> > > + hci_conn_drop(iso_pi(sk)->conn->hcon);
> > > + }
> > > iso_conn_unlock(iso_pi(sk)->conn);
> > > }
> > >
> > > --
> > > 2.55.0
> > >
> >
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes
2026-07-20 18:30 [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes Pauli Virtanen
2026-07-20 19:37 ` Luiz Augusto von Dentz
@ 2026-07-20 20:30 ` bluez.test.bot
1 sibling, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-07-20 20:30 UTC (permalink / raw)
To: linux-bluetooth, pav
[-- Attachment #1: Type: text/plain, Size: 1235 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1131089
---Test result---
Test Summary:
CheckPatch PASS 0.58 seconds
VerifyFixes PASS 0.08 seconds
VerifySignedoff PASS 0.09 seconds
GitLint PASS 0.21 seconds
SubjectPrefix PASS 0.07 seconds
BuildKernel PASS 27.98 seconds
CheckAllWarning PASS 30.13 seconds
CheckSparse PASS 29.14 seconds
BuildKernel32 PASS 27.30 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 518.84 seconds
TestRunner_iso-tester PASS 84.67 seconds
IncrementalBuild PASS 26.36 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
https://github.com/bluez/bluetooth-next/pull/465
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-20 20:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 18:30 [PATCH v2] Bluetooth: ISO: fix UAF on socket close before shutdown completes Pauli Virtanen
2026-07-20 19:37 ` Luiz Augusto von Dentz
2026-07-20 20:08 ` Pauli Virtanen
2026-07-20 20:14 ` Luiz Augusto von Dentz
2026-07-20 20:30 ` [v2] " bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox