[BUG] Bluetooth: ISO: listener sock leaked when iso_sock_alloc() fails

From: Qingyu Zhang

Date: Tue Sep 01 2026 - 22:11:12 EST


Hello,

iso_conn_ready() leaks a reference on the ISO listening socket when
child allocation fails. A patch is attached.

Type: memory leak (sock reference)

* Summary

iso_get_sock() does sock_hold(parent). iso_conn_ready() then:

lock_sock(parent);
sk = iso_sock_alloc(..., GFP_ATOMIC, 0);
if (!sk) {
release_sock(parent);
return; /* missing sock_put(parent) */
}

The success path and the "listener closed concurrently" path (after
560bef609fa5) both sock_put(parent). This failure path does not.

* Affected

Introduced with BTPROTO_ISO (ccf74f2390d6). Still present on
08dbfad3f504. Needs CONFIG_BT=m, CONFIG_BT_ISO, HCI_VHCI, kmemleak
and (for a reliable trigger) CONFIG_FAILSLAB.

* Reproduction

1. Boot with kmemleak=on and failslab.
2. Bring up a virtual controller (hci_vhci).
3. ISO socket: bind + BT_DEFER_SETUP + listen.
4. Inject HCI LE Enhanced Connection Complete, then LE CIS Request
(subevent 0x1a) while failslab is armed for GFP_ATOMIC
(ignore-gfp-wait=Y, probability=100, times=-1) so iso_sock_alloc()
returns NULL.
5. close() the listen fd, then:

echo scan > /sys/kernel/debug/kmemleak

kmemleak shows the listen sock (size 2048, iso_sock_create ->
iso_sock_alloc). rmmod bluetooth then fails with EBUSY.

PoC: poc/vhci_iso.c (the "#47 failslab GFP_ATOMIC window around
CIS_REQ" section). Full QEMU recipe is in poc/run.sh.

* Expected

iso_sock_alloc() failure drops the iso_get_sock() reference, same as
the other return paths in iso_conn_ready().

* Actual

sk_refcnt stays elevated. The listen sock is never freed.

Please consider the suggested patch.

Thanks.

Suggested patch:
```
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 75bfd5938b2e..4de332b8901f 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2289,6 +2289,7 @@ static void iso_conn_ready(struct iso_conn *conn)
BTPROTO_ISO, GFP_ATOMIC, 0);
if (!sk) {
release_sock(parent);
+ sock_put(parent);
return;
}
```