---
id: "CVE-2026-98735"
kind: "vulnerability"
aliases: ["CVE-2026-98735"]
title: "Linux kernel: Bluetooth channel teardown race causes use-after-free"
severity: "unknown"
cvss: null
epss: null
exploited: false
status: "open"
category: "runtime"
products: []
ecosystems: []
tags: ["bluetooth", "kernel", "linux", "runtime", "self-hosted"]
not_affected_if: ["default-config"]
published_at: "2026-10-18T16:17:27+00:00"
first_seen_at: "2026-10-23T21:57:16+00:00"
updated_at: "2026-10-25T05:17:10+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-98735", "first_seen_at": "2026-10-23T21:57:16+00:00"}]
---

# Linux kernel: Bluetooth channel teardown race causes use-after-free

The Linux kernel Bluetooth stack can use a freed ACL channel when a disconnect timeout runs while transmission selects that channel. An attacker able to trigger connection teardown may be able to corrupt kernel memory, and the sources do not state a code execution outcome.

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

## How to check

- Run `uname -r` and compare against the kernel version that contains the upstream fix for CVE-2026-98735 (unknown from these sources)
- Check whether the Bluetooth stack is loaded with `lsmod | grep bluetooth`

## Fix

- Install a Linux kernel build that includes the upstream commit 'Bluetooth: hci_core: Serialize ACL scheduling with channel deletion' (fixed version unknown from these sources)
- Reboot into the patched kernel

## Timeline

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

## From the sources

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

Bluetooth: hci_core: Serialize ACL scheduling with channel deletion

hci_chan_sent() selects a channel under RCU but drops the read lock before
accessing chan->conn and returning the channel. The ACL and LE schedulers
then use its packet queue and update its transmit counters without any
protection against channel deletion.

After TX selects a channel and releases RCU, a disconnect command timeout
on the separate request workqueue can run hci_conn_failed() and
l2cap_conn_del(). hci_chan_del() can then unlink the channel, complete
synchronize_rcu(), purge its queue and free it before TX resumes. This
causes use-after-free both in hci_chan_sent() and in its callers.

KASAN reported:

  BUG: KASAN: slab-use-after-free in hci_chan_sent+0x892/0x9b0
  Workqueue: hci0 hci_tx_work
  Call Trace:
   hci_chan_sent+0x892/0x9b0
   hci_tx_work+0x5e6/0xb70
  Allocated by task 91:
   hci_chan_create+0xe3/0x350
   l2cap_conn_add.part.0+0x12/0xa30
   l2cap_chan_connect+0x110d/0x1b60
   l2cap_sock_connect+0x310/0x530
  Freed by task 99:
   hci_chan_del+0x11f/0x170
   l2cap_conn_del+0x4f1/0x800
   l2cap_connect_cfm+0x88c/0xd30
   hci_conn_failed+0x150/0x250
   hci_abort_conn_sync+0x3e3/0x800
   hci_cmd_sync_run+0x7e/0xc0
   hci_abort_conn+0x105/0x1f0
   disconnect_sync+0x157/0x290
   hci_cmd_sync_work+0x13c/0x290

Hold the existing device mutex across channel selection and transmission
in both schedulers to serialize them with channel teardown. Keep timeout
handling outside the critical sections because hci_link_tx_to() acquires
the same mutex. This also permits the transmit path to sleep, unlike
extending the RCU read-side critical section across packet submission.

---

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