[PATCH] Bluetooth: ISO: fix UAF in iso_conn_ready

From: Jiale Yao

Date: Sat Jul 25 2026 - 06:51:59 EST


When iso_connect_cfm() calls iso_conn_ready(), the latter reads
conn->sk without holding a reference. A concurrent close() on the
ISO socket triggers iso_sock_kill() which frees sk, leading to a
use-after-free when iso_conn_ready() subsequently accesses the
freed sk via lock_sock() and iso_sock_ready().

This was triggered by a vhci-based PoC that races
LE Setup ISO Data Path (0x206e) command completion against
close() on the ISO socket. The crash manifests as a KASAN
null-ptr-deref in iso_connect_cfm() at offset 0x3c from a NULL
pointer, with the call trace:

iso_connect_cfm+0x311/0x15f0
hci_cc_le_setup_iso_path+0x46d/0x6f0
hci_cmd_complete_evt+0x26d/0x990
hci_event_packet+0x468/0xb40
hci_rx_work+0x255/0x6e0

Fix by replacing the bare pointer read with iso_sock_hold(conn)
under iso_conn_lock, which atomically elevates the refcount,
and add sock_put() on the exit path where the hold succeeded.

Fixes: ccf74f2390d60 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
---
net/bluetooth/iso.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 2e95a153912c..c8103de41cdd 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2074,7 +2074,7 @@ static bool iso_match_dst(struct sock *sk, void *data)
static void iso_conn_ready(struct iso_conn *conn)
{
struct sock *parent = NULL;
- struct sock *sk = conn->sk;
+ struct sock *sk;
struct hci_ev_le_big_sync_established *ev = NULL;
struct hci_ev_le_pa_sync_established *ev2 = NULL;
struct hci_ev_le_per_adv_report *ev3 = NULL;
@@ -2083,6 +2083,10 @@ static void iso_conn_ready(struct iso_conn *conn)

BT_DBG("conn %p", conn);

+ iso_conn_lock(conn);
+ sk = iso_sock_hold(conn);
+ iso_conn_unlock(conn);
+
if (sk) {
/* Attempt to update source address in case of BIS Sender if
* the advertisement is using a random address.
@@ -2103,7 +2107,8 @@ static void iso_conn_ready(struct iso_conn *conn)
}
}

- iso_sock_ready(conn->sk);
+ iso_sock_ready(sk);
+ sock_put(sk);
} else {
hcon = conn->hcon;
if (!hcon)
--
2.34.1