CVE-2026-19939 in Zephyr
Summary
by MITRE • 10/13/2026
The AVDTP signalling layer arms a 6-second command timeout (AVDTP_TIMEOUT) in avdtp_send_cmd() whenever the local device issues an AVDTP request. Every response handler in subsys/bluetooth/host/classic/avdtp.c cancels session->timeout_work before clearing the pending request, but bt_avdtp_l2cap_disconnected() only cleared session->req and left the delayable work armed. The struct bt_avdtp session is the first member of struct bt_a2dp, whose instances live in a static per-connection array, and a2dp_get_connection() in subsys/bluetooth/host/classic/a2dp.c wipes a slot with memset() as soon as session->br_chan.chan.conn is NULL — which the L2CAP layer arranges immediately after the disconnect callback returns.
A remote Bluetooth BR/EDR peer triggers the condition by opening the AVDTP signalling channel, letting the local application issue an AVDTP procedure (the standard A2DP flow issues bt_a2dp_discover() from the connected callback), then tearing the signalling channel down without responding and re-opening it within the remaining timeout window. The reconnect reaches a2dp_accept() → a2dp_get_connection(), which zeroes the whole struct bt_a2dp while the work item's struct _timeout is still linked into the kernel's global timeout list. Both the disconnect and the reconnect instants are chosen by the attacker, so no race has to be won; an encrypted BR/EDR link is required, and CONFIG_BT_A2DP (experimental) must be enabled.
With the default CONFIG_TIMEOUT_BACKEND_DLIST backend the kernel decides a timeout is inactive by testing whether its list node is linked, so after the memset() the kernel treats a node that is still on the global timeout list as free: the announce path pops a node whose links and handler pointer are NULL, and the next bt_work_reschedule() on the recycled session re-inserts the same node into a list that already contains it. The consequence is corruption of the single kernel data structure every timer, timeslice and sleep depends on — writes through zeroed or stale list pointers and a NULL handler dispatch — producing a system-wide crash or hang rather than a fault confined to the A2DP session.
The fix cancels session->timeout_work at the top of bt_avdtp_l2cap_disconnected() and moves k_work_init_delayable() from avdtp_send_cmd() to the session-establishment paths bt_avdtp_connect() and bt_avdtp_l2cap_accept(), so the work item is always initialized before a disconnect callback can run.
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 10/14/2026
The vulnerability resides within the Bluetooth Audio/Video Distribution Transport protocol implementation in the Linux kernel, specifically affecting the Advanced Audio Distribution Profile subsystem when experimental support for A2DP is enabled. The core technical flaw stems from an improper handling of delayed work items during L2CAP channel disconnection events. When a local device issues an AVDTP request via avdtp_send_cmd(), a six-second command timeout is armed using a delayable kernel work item. While most response handlers correctly cancel this pending work before clearing the session state, the disconnect handler bt_avdtp_l2cap_disconnected() fails to cancel the timer. It only clears the pending request pointer but leaves the underlying struct _timeout node linked in the global kernel timeout list. This oversight creates a critical race condition where the lifecycle of the timer is not synchronized with the lifecycle of the session data structure it references.
The operational impact arises from how memory management interacts with this stale timer reference. The bt_avdtp_session structure is embedded as the first member within struct bt_a2dp, which resides in a static per-connection array managed by the A2DP subsystem. When an L2CAP disconnect occurs, the connection object is nullified immediately after the callback returns. Subsequently, when a new AVDTP signalling channel is opened and accepted, the function a2dp_get_connection() invokes memset to zero out the entire bt_a2dp slot in preparation for reuse. Because the previous timer was never cancelled, its struct _timeout node remains linked in the global timeout list despite the underlying session data being wiped. This results in use-after-free semantics where the kernel retains references to memory that has been logically freed and repurposed.
An attacker can exploit this condition by manipulating the timing of Bluetooth connections. The attack requires an encrypted BR/EDR link, which is standard for most secure audio profiles. The adversary opens the AVDTP signalling channel, triggers a local application to issue an AVDTP procedure such as discovery, and then immediately tears down the signalling channel without sending a response. Within the six-second timeout window, the attacker re-opens the channel. This forces the kernel to reuse the same session slot while the old timer is still active in the background. When the system attempts to process timeouts or reschedule work on this recycled session, it interacts with corrupted list pointers and NULL handler functions. The default CONFIG_TIMEOUT_BACKEND_DLIST backend relies on checking if a node is linked to determine activity status; since the zeroed-out node remains linked, the kernel incorrectly treats it as active but devoid of valid data structures.
The consequences of this memory corruption are severe and system-wide rather than confined to the specific audio session. The corrupted list pointers lead to writes through invalid addresses or NULL dereferences during timer dispatch operations. This can cause a complete kernel panic, system hang, or unpredictable behavior affecting other subsystems that depend on the same global timeout data structures. Unlike typical local privilege escalation vulnerabilities, this flaw allows for denial of service against the entire operating system from a remote attacker who has established an authenticated Bluetooth connection. The lack of proper synchronization between session teardown and timer cancellation means that no complex race condition timing is required; the vulnerability triggers deterministically upon reconnection within the timeout period.
Mitigation strategies involve both immediate patching and architectural improvements to the protocol stack implementation. The primary fix requires cancelling the session->timeout_work at the very beginning of bt_avdtp_l2cap_disconnected() to ensure no stale timers remain active when the connection state is cleared. Additionally, initialization logic for delayable work items must be moved from command sending functions to session establishment paths like bt_avdtp_connect and bt_avdtp_l2cap_accept. This ensures that every timer instance is properly initialized before any disconnect callback can potentially access it. From a defensive standpoint, administrators should ensure CONFIG_BT_A2DP remains disabled if not strictly necessary, as this feature set introduces the vulnerable code path. Regular kernel updates are essential to apply these synchronization fixes and prevent remote denial of service attacks via Bluetooth audio protocols.
This vulnerability aligns with CWE-416 Use After Free, where a pointer is used after it has been freed or invalidated due to improper lifecycle management. It also relates to CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization, as the timer and session data are accessed concurrently without adequate locking or cancellation mechanisms during state transitions. In terms of MITRE ATT&CK mapping, this represents a Remote Code Execution vector leading to Denial of Service via resource exhaustion or memory corruption in kernel space. The attack pattern involves manipulating connection states to trigger internal logic errors that compromise system stability rather than gaining direct code execution privileges immediately. Security audits should focus on verifying that all asynchronous work items are explicitly cancelled during teardown sequences across the Bluetooth stack to prevent similar issues in other protocol layers.