---
id: "CVE-2026-98809"
kind: "vulnerability"
aliases: ["CVE-2026-98809"]
title: "Linux kernel: Bluetooth unregister can hang for hours on command backlog"
severity: "low"
cvss: null
epss: null
exploited: false
status: "open"
category: "other"
products: []
ecosystems: []
tags: ["bluetooth", "linux-kernel", "other", "self-hosted"]
not_affected_if: ["no-bluetooth-hardware", "vhci-not-loaded"]
published_at: "2026-10-18T16:17:34+00:00"
first_seen_at: "2026-10-23T21:57:16+00:00"
updated_at: "2026-10-25T05:14:59+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-98809", "first_seen_at": "2026-10-23T21:57:16+00:00"}]
---

# Linux kernel: Bluetooth unregister can hang for hours on command backlog

A local user can queue many Bluetooth management commands to a controller that never replies, then closing the vhci device stalls the kernel thread for hours. The sources describe a denial of service, not code execution.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- Run `uname -r` and compare with the fixed kernel versions in the advisory (unknown from sources)
- Check whether the vhci_hci driver is loaded with `lsmod | grep hci_vhci`

## Fix

- Update the Linux kernel to a release that includes the upstream commit 'Bluetooth: hci_sync: don't drain cmd_sync backlog on unregister' (fixed versions unknown from sources)

## Timeline

- 2026-10-23T21:57:16+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-98809

## From the sources

In the Linux kernel, the following vulnerability has been resolved:

Bluetooth: hci_sync: don't drain cmd_sync backlog on unregister

hci_unregister_dev() disables cmd_work and cmd_timer, then calls
hci_cmd_sync_clear(), whose cancel_work_sync() waits for
hci_cmd_sync_work() to return. That worker dequeues and runs every
entry on cmd_sync_work_list. With cmd_work disabled nothing reaches
the controller, so each queued HCI command waits the full
HCI_CMD_TIMEOUT (2s).

The backlog has no bound. Userspace can keep queuing MGMT commands
such as MGMT_OP_GET_CLOCK_INFO against a controller that doesn't
answer. Closing /dev/vhci then blocks in vhci_release() for
backlog * 2s:

  INFO: task syz-executor:5749 blocked for more than 143 seconds.
   cancel_work_sync
   hci_cmd_sync_clear
   hci_unregister_dev
   vhci_release

In a local reproduction the backlog held more than 5000 entries,
which comes to hours of hang.

Stop the worker from taking new entries once HCI_UNREGISTER is set,
and wake any request still waiting with -ENODEV before cancelling
the work. The entries left over are destroyed with -ECANCELED by the
existing sweep in hci_cmd_sync_clear(). They stay on the list until
the work has stopped, so hci_cmd_sync_dequeue() and friends still see
them. A callback already running may still issue another command,
which delays unregister by at most one timeout per remaining command,
not by the whole backlog.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
