CVE-2026-92241 · Runtime
NO FIX YET
A paired Bluetooth Classic peer that opens the AVRCP browsing channel and streams segmented L2CAP data can exhaust a receive-buffer pool and block the Bluetooth RX thread forever. The result is a permanent hang of all Bluetooth host processing on the device until reboot, with no code execution or data exposure reported.
first public Nov 13, 2026 · 1 source
Check it with your coding agent
It reads this page and tells you if your code or app is affected.
Only builds that enable both CONFIG_BT_CLASSIC and the experimental CONFIG_BT_AVRCP_BROWSING option and register AVRCP callbacks are exposed. The attacker must be a BR/EDR peer already paired with the device, since the browsing channel needs an encrypted link. Devices without these options can skip it.
Not affected if ble-only, default-config, no-avrcp-browsing, unpaired-peers
Who cares avrcp, bluetooth, embedded, zephyr
CONFIG_BT_CLASSIC and the experimental CONFIG_BT_AVRCP_BROWSING optionUnknown from the sources.
The AVRCP browsing channel's L2CAP receive-buffer callback, browsing_avrcp_l2cap_alloc_buf() in subsys/bluetooth/host/classic/avrcp.c, allocated from the shared avctp_browsing_rx_pool with K_FOREVER. L2CAP invokes that callback from the Bluetooth RX work queue thread (bt_workq, "BT RX WQ"), both for the head buffer of a new SDU and — through l2cap_br_alloc_frag() and net_buf_append_bytes() — for every further fragment of a reassembled SDU. That same thread is the only context that ever releases these buffers, after bt_l2cap_br_recv_seg() delivers a completed SDU and calls net_buf_unref(), so a wait taken there can never be satisfied.
The pool holds CONFIG_BT_MAX_CONN + 1 buffers of CONFIG_BT_AVRCP_BROWSING_L2CAP_MTU bytes (two buffers of 339 bytes in the default configuration). A connected browsing peer can drain it because bt_l2cap_br_recv_seg() in subsys/bluetooth/host/classic/l2cap_br.c accepts the SDU length declared in an SAR_START segment without bounding it by br_chan->rx.mtu: a peer that announces a large SDU and then streams continuation segments forces one pool buffer per segment-worth of data. Once the pool is empty the next allocation blocks forever inside the callback.
Triggering the flaw requires a build with CONFIG_BT_CLASSIC and the experimental CONFIG_BT_AVRCP_BROWSING option, an application that registers AVRCP callbacks, and a BR/EDR peer that has established the AVRCP control channel and then the browsing channel, which requires an encrypted (paired) link. No malformed packet is needed — a few hundred bytes of ordinary segmented L2CAP traffic suffice.
The consequence is a permanent hang of the whole Bluetooth host, not just of AVRCP: the blocked thread drains bt_dev.rx_queue for all HCI ACL data and low-priority events and also runs the host's internal work items, so all connections stop being serviced and the state is unrecoverable without a reboot. There is no memory-corruption or information-disclosure component. The fix allocates with K_NO_WAIT, so an empty pool now yields a local-busy indication or a channel disconnect that the application can recover from.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
InfraStack checks it against your stack and answers on your report, with the evidence and the fix.
This page as .md · .json · CVSS:3.1/AV:A/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.