Description
The Bluetooth Classic Hands-Free Profile Audio Gateway implementation in subsys/bluetooth/host/classic/hfp_ag.c keeps its struct bt_hfp_ag objects in a static pool indexed by ACL connection index. On link teardown, hfp_ag_disconnected() cancels ag->tx_work and the per-call work items and then clears ag->acl_conn, which marks the pool slot as free — but it leaves ag->ongoing_call_work (and ag->slc_work) untouched. The next connection that lands on the same slot enters hfp_ag_create(), whose only occupancy test is ag->acl_conn, and immediately executes memset(ag, 0, sizeof(struct bt_hfp_ag)) followed by k_work_init_delayable(). Zeroing and re-initialising a k_work_delayable whose struct _timeout node is still linked into the kernel timeout list leaves the kernel holding a reference to a node with NULL prev/next links.

ag->ongoing_call_work is armed by the remote peer: when a Hands-Free unit sends AT+CIND? during Service Level Connection establishment and the application provides the asynchronous get_ongoing_call callback, the AG schedules the work for CONFIG_BT_HFP_AG_GET_ONGOING_CALL_TIMEOUT milliseconds (default 10000). The timer is cancelled only if the application answers in time via bt_hfp_ag_ongoing_calls(). A peer that sends AT+CIND?, then disconnects the HFP RFCOMM DLC, then immediately re-opens it on the same ACL link, reuses the same pool slot deterministically while the timeout is still pending — the AG's RFCOMM server accept path (hfp_ag_accept()) calls hfp_ag_create() directly, so the remote side drives both teardown and re-creation.

The result is corruption of the kernel's timeout list: sys_dlist_remove() on the zeroed node performs writes through NULL pointers from the clock-announce path, and rescheduling the re-initialised work re-inserts a node the list already references, creating a cycle that the announce loop walks with interrupts locked. The observable impact is a fault or hang of the whole system, i.e. a denial of service reachable from Bluetooth radio range; no attacker-controlled data is written, so this does not by itself yield code execution. Exposure is limited to builds with CONFIG_BT_HFP_AG (marked experimental and disabled by default) whose application implements the asynchronous get_ongoing_call callback.
Published: 2026-10-13
Score: 6.5 Medium
EPSS: n/a
KEV: No
Impact: Denial of Service via Bluetooth radio range
Action: Patch Now
AI Analysis

Impact

A flaw in the Zephyr Bluetooth Hands‑Free Profile Audio Gateway implementation reuses a connection slot while a delayable work item remains armed, corrupting the kernel’s timeout book‑keeping. The corrupted kernel timeout list leads to a system fault or hang, effectively denying service. No attacker‑controlled data is written, so code execution is not achievable.

Affected Systems

Builds of Zephyr RTOS that enable Bluetooth HFP AG (CONFIG_BT_HFP_AG) and implement the asynchronous get_ongoing_call callback are affected. The flaw arises when a Hands‑Free unit sends AT+CIND? during Service Level Connection establishment, disconnects, and then immediately reconnects on the same ACL link, forcing reuse of a static pool slot used by the AG.

Risk and Exploitability

The CVSS score of 6.5 indicates medium severity. EPSS is not available and the vulnerability is not listed in the CISA KEV catalog. The attack is reachable from the Bluetooth radio range and can be performed by sending specific AT commands to trigger a disconnect/reconnect sequence, resulting in a denial of service. Official disclosures do not indicate a readily available exploit library.

Generated by OpenCVE AI on October 13, 2026 at 19:18 UTC.

Remediation

No solution or workaround provided in the CVE record.

OpenCVE Recommended Actions

  • Apply the Zephyr core update that includes the fixed commit 204c36b896fe8d68ca3cb3d00216f245f91d14be.
  • If a patch is not yet available, disable the CONFIG_BT_HFP_AG configuration option or remove the HFP AG module from the build.
  • Ensure that any asynchronous get_ongoing_call callbacks are not implemented or are guarded so that the AG does not schedule delayable work while a disconnect may still be pending.

Generated by OpenCVE AI on October 13, 2026 at 19:18 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Tue, 13 Oct 2026 17:00:00 +0000

Type Values Removed Values Added
Description The Bluetooth Classic Hands-Free Profile Audio Gateway implementation in subsys/bluetooth/host/classic/hfp_ag.c keeps its struct bt_hfp_ag objects in a static pool indexed by ACL connection index. On link teardown, hfp_ag_disconnected() cancels ag->tx_work and the per-call work items and then clears ag->acl_conn, which marks the pool slot as free — but it leaves ag->ongoing_call_work (and ag->slc_work) untouched. The next connection that lands on the same slot enters hfp_ag_create(), whose only occupancy test is ag->acl_conn, and immediately executes memset(ag, 0, sizeof(struct bt_hfp_ag)) followed by k_work_init_delayable(). Zeroing and re-initialising a k_work_delayable whose struct _timeout node is still linked into the kernel timeout list leaves the kernel holding a reference to a node with NULL prev/next links. ag->ongoing_call_work is armed by the remote peer: when a Hands-Free unit sends AT+CIND? during Service Level Connection establishment and the application provides the asynchronous get_ongoing_call callback, the AG schedules the work for CONFIG_BT_HFP_AG_GET_ONGOING_CALL_TIMEOUT milliseconds (default 10000). The timer is cancelled only if the application answers in time via bt_hfp_ag_ongoing_calls(). A peer that sends AT+CIND?, then disconnects the HFP RFCOMM DLC, then immediately re-opens it on the same ACL link, reuses the same pool slot deterministically while the timeout is still pending — the AG's RFCOMM server accept path (hfp_ag_accept()) calls hfp_ag_create() directly, so the remote side drives both teardown and re-creation. The result is corruption of the kernel's timeout list: sys_dlist_remove() on the zeroed node performs writes through NULL pointers from the clock-announce path, and rescheduling the re-initialised work re-inserts a node the list already references, creating a cycle that the announce loop walks with interrupts locked. The observable impact is a fault or hang of the whole system, i.e. a denial of service reachable from Bluetooth radio range; no attacker-controlled data is written, so this does not by itself yield code execution. Exposure is limited to builds with CONFIG_BT_HFP_AG (marked experimental and disabled by default) whose application implements the asynchronous get_ongoing_call callback.
Title Bluetooth HFP AG reuses a connection slot while a delayable work item is still armed, corrupting kernel timeout bookkeeping
Weaknesses CWE-416
References
Metrics cvssV3_1

{'score': 6.5, 'vector': 'CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'}


Subscriptions

No data.

cve-icon MITRE

Status: PUBLISHED

Assigner: zephyr

Published:

Updated: 2026-10-13T16:40:10.541Z

Reserved: 2026-08-15T13:31:23.585Z

Link: CVE-2026-19940

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Received

Published: 2026-10-13T17:17:40.107

Modified: 2026-10-13T17:17:40.107

Link: CVE-2026-19940

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-10-13T19:30:12Z

Weaknesses