Where
-Infinity
0
Severity
7.1
AV:A/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H

btisorecv() in subsys/bluetooth/host/iso.c pulled the ISO SDU header (4 bytes) or, when the timestamp flag is set, the timestamped SDU header (8 bytes) from the inbound HCI ISO Data buffer via netbufpullmem() without first checking buf->len. The upstream hciiso() handler enforces buf->len == the controller-declared ISO DataLoad length, so a malicious or buggy controller / adjacent BLE peer on an established CIS/BIS can present a first-fragment (BTISOSTART) or single (BTISOSINGLE) PDU shorter than the SDU header. Because netbufsimplepullmem only guards length with ASSERTNOMSG (compiled out when CONFIGASSERT is disabled, the production default), the pull underflows buf->len (uint16t, e.g. 0 - 8 = 0xFFF8) and advances buf->data past valid data: the subsequent reads of hdr->slen and hdr->sn are out-of-bounds reads of adjacent pool memory. For the multi-fragment (START) case the corrupted buffer is retained as iso->rx, and a following CONT/END fragment's netbuftailroom() guard underflows to a near-SIZEMAX value, defeating the bounds check and causing netbufaddmem() to memcpy attacker-supplied fragment data far past the RX pool buffer (out-of-bounds write). The flaw affects ISO receive builds (CONFIGBTISORX, selected by the default-off LE Audio options BTISOPERIPHERAL/BTISOCENTRAL/BTISOSYNCRECEIVER) and has existed since the ISO subsystem was introduced (v2.6.0) through v4.4.0. The fix adds explicit buf->len < sizeof(tshdr) and buf->len < sizeof(hdr) checks that drop the buffer before pulling.

First published (updated )
Severity
5.9
Use After Free, Double Free
AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H

The Bluetooth host's ATT transmit path releases a buffer it does not own when signing fails. chansend() in subsys/bluetooth/host/att.c documents (and every other error exit implements) the contract that on failure the caller retains ownership of the netbuf; the BTATTOPSIGNEDWRITECMD branch instead called netbufunref(buf) when btsmpsign() returned an error and then returned that error to the caller. The callers act on the contract: processqueue() re-queues the buffer with kqueueprepend(), btattchansendrsp() puts it back on chan->txqueue, btattchanreqsend() restores it into the request, and attreqretry() unreferences it — so the already-freed buffer was re-queued, later dereferenced, and eventually freed again.

An ATT Signed Write Command is produced when an application calls btgattwritewithoutresponsecb() with sign set on an unencrypted connection. btsmpsign() fails whenever no local CSRK exists for the peer (-ENOENT), and whether one exists is negotiated with the peer: smpdistributekeys() stores a local CSRK only when the peer's pairing key-distribution field requests the signing key and bonding was agreed. A peer can therefore pair without accepting the CSRK, pair with No Bonding, remain unpaired, or keep the link unencrypted, and the victim's next signed write takes the failing path. Because struct netbuf's node field is simultaneously the linkage word for the ATT TX FIFO, for the deferred-destroy list used by the attpool destroy callback atttxdestroy(), and for the pool free list, the mishandled buffer corrupts these lists and can be re-issued by btattcreatepdu() to a new PDU while the ATT TX path still holds it.

The same branch also saved the netbufsimplestate only after signing, so a buffer restored after a btl2capsendpdu() failure kept its 12-octet signature; a subsequent retry re-signed it and appended a second signature with netbufadd(buf, 12) to a buffer that btattcreatepdu() sized for exactly one, writing past the end of the pooled buffer in builds where the netbuf tailroom assertion is compiled out.

Impact is host-side memory corruption in the Bluetooth stack: list corruption, a pooled ATT buffer with two owners (wrong PDU contents transmitted, or a double free when the queues are drained at disconnect), and a bounded out-of-bounds write on the retry path — typically observed as a crash or assertion failure. Exposure requires the deprecated CONFIGBTSIGNING to be enabled and an application that actually issues signed writes; in that configuration the triggering condition is under the remote peer's control.

First published (updated )
Severity
4.3
AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

The Bluetooth host pre-allocates a btconn object (a "reservation") from the fixed aclconns[] pool for every connectable advertising set it starts, in leadvstartaddconn() in subsys/bluetooth/host/adv.c. When an incoming peripheral connection completes, findpendingconnect() in subsys/bluetooth/host/hcicore.c looked that reservation up using only the identity and the peer address, with a directed-then-undirected fallback, and had no knowledge of which advertising set actually terminated. With CONFIGBTEXTADVMAXADVSET > 1, where the LE Enhanced Connection Complete event is cached until the LE Advertising Set Terminated event identifies the set, this lookup can return the reservation belonging to a different, still-running advertising set.

The defect is reachable over the air by any adjacent device. If an application runs two connectable extended advertising sets on the same identity — one undirected and one directed at a peer P (the common "directed reconnect to a bonded central while still accepting new centrals" pattern) — a remote initiator whose address maps to P connecting on the undirected set causes the directed set's reservation to be consumed instead. The initiator address is chosen freely by the remote device and is not authenticated at link establishment, so no bonding, pairing or prior relationship is required to trigger the mis-attribution.

The undirected set's own reservation is then stranded: its BTADVENABLED flag has already been cleared, and leadvstopfreeconn() — the only path that returns a reservation to the pool — is reached only for sets that are still enabled, so btleextadvstop() returns early and the object is never released. Each occurrence permanently consumes one CONFIGBTMAXCONN slot until btdisable() or reboot. In application patterns that restart the directed advertising set after each disconnect, an attacker can repeat the sequence until the pool is exhausted, after which connectable advertising fails with -ENOMEM and the device can no longer accept connections. As a side effect the directed set keeps advertising without a reservation, so a genuine connection on it is dropped by bthcidisconnect(). The impact is availability only; no memory corruption or information disclosure results, and configurations with a single advertising set are unaffected.

First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203