CVE-2026-98737: Bluetooth: hci_sync: Fix inquiry cache use-after-free
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: hcisync: Fix inquiry cache use-after-free
The sync command worker holds hdev->reqlock, but inquiry-cache updates and flushes use hdev->lock. Both hciaclcreateconnsync() and hcistopdiscoverysync() look up entries and read their fields without taking hdev->lock.
After either lookup returns, a concurrent HCIINQUIRY ioctl can acquire hdev->lock and flush the cache, freeing the entry. The worker then reads the freed entry while preparing a create-connection or remote-name-cancel command. The list traversal also races with cache updates and removal.
KASAN reported these accesses:
BUG: KASAN: slab-use-after-free in hciaclcreateconnsync+0x5f1/0x650 Workqueue: hci0 hcicmdsyncwork Call Trace: hciaclcreateconnsync+0x5f1/0x650 hcicmdsyncwork+0x13c/0x290
Allocated by task 90: hciinquirycacheupdate+0x3e6/0x7d0 hciinquiryresultevt+0x3cb/0x560
Freed by task 93: hciinquirycacheflush+0x111/0x2b0 hciinquiry+0x2f2/0x780 hcisockioctl+0x269/0x5f0
BUG: KASAN: slab-use-after-free in hcistopdiscoverysync+0x3b1/0x3c0 Workqueue: hci0 hcicmdsyncwork Call Trace: hcistopdiscoverysync+0x3b1/0x3c0 hcicmdsyncwork+0x173/0x300
Allocated by task 86: hciinquirycacheupdate+0x483/0x940 hciinquiryresultevt+0x3cb/0x560
Freed by task 91: hciinquirycacheflush+0x13e/0x2f0 hciinquiry+0x2f2/0x780 hcisockioctl+0x269/0x5f0
Hold hdev->lock across each lookup and all reads from its result. Copy the remote address before unlocking so discovery cancellation does not retain a cache entry pointer. Release the lock before sending synchronous HCI commands, since their completion handlers may need the same lock.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
In the Bluetooth HCI inquiry-cache code, hold hdev->lock across each cache lookup and all reads from the result; copy the remote address before unlocking, release the lock before sending synchronous HCI commands, and ensure cache traversal is synchronized with cache updates and removal.
Event History
Frequently Asked Questions
What conditions are required to trigger the race?
A synchronous create-connection or stop-discovery worker must look up an inquiry-cache entry while a concurrent HCIINQUIRY ioctl flushes that cache. The flush can free the entry after the lookup returns, and the worker can then access the freed entry while preparing a create-connection or remote-name-cancel command.
How can I tell whether this issue has occurred?
KASAN can report a slab use-after-free in hci_acl_create_conn_sync or hci_stop_discovery_sync, with hci_cmd_sync_work on the workqueue stack. The reported allocation path includes hci_inquiry_cache_update, while the free path includes hci_inquiry_cache_flush, hci_inquiry, and hci_sock_ioctl.