Bluetooth: hci_sync: Fix accept list UAF during suspend
Subsystems (3)
PATCH v2 1/1 Bluetooth: hci_sync: Fix accept list UAF during suspend
hci_update_event_filter_sync() walks hdev->accept_list while sending a synchronous HCI command for each remote-wakeup device. The suspend path holds hdev->req_lock, but accept-list updates are serialized by hdev->lock. Consequently, remove_device() can free the current list entry during the controller wait.
The following interleaving causes the use-after-free:
hci_update_event_filter_sync() remove_device()
fetch accept-list entry
hci_set_event_filter_sync()
wait for controller response hci_dev_lock()
list_del()
kfree()
hci_dev_unlock()read the freed list.next
KASAN reported:
BUG: KASAN: slab-use-after-free in hci_suspend_sync+0x835/0x910 Read of size 8 at addr ffff88810bec8440 by task kworker/0:1/10 Workqueue: events vhci_suspend_work Call Trace: hci_suspend_sync+0x835/0x910 hci_suspend_dev+0x182/0x450 process_one_work+0x661/0x1090 worker_thread+0x45b/0xd10 Allocated by task 86: hci_bdaddr_list_add_with_flags+0x1a8/0x400 add_device+0x381/0x820 hci_sock_sendmsg+0x1033/0x1ea0 Freed by task 91: kfree+0x131/0x3c0 remove_device+0x429/0xb70 hci_sock_sendmsg+0x1033/0x1ea0
Snapshot the remote-wakeup addresses under hdev->lock. Release the lock before sending HCI commands. Clear the controller event filter before building the snapshot, and skip allocation and the second list traversal when there are no matching entries. This preserves the original filter and scan-state updates without retaining an accept-list node across a controller wait.
---
Changes in v2:
- Clear the event filter before taking the accept-list snapshot.
- Skip allocation and the second list walk when there are no matching entries.
net/bluetooth/hci_sync.c | 46 ++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-)
net/bluetooth/hci_sync.c +37 -9
@@ -6313,6 +6313,8 @@ static int hci_pause_discovery_sync(struct hci_dev *hdev)static int hci_update_event_filter_sync (struct hci_dev *hdev) {struct bdaddr_list_with_flags *b; +bdaddr_t *accept_list; +size_t i, num_entries =0 ;u8 scan =SCAN_DISABLED ;bool scanning =test_bit (HCI_PSCAN , &hdev->flags);int err;
@@ -6329,23 +6331,49 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)/* Always clear event filter when starting */ hci_clear_event_filter_sync (hdev); -list_for_each_entry (b, &hdev->accept_list, list) { -if (!(b->flags &HCI_CONN_FLAG_REMOTE_WAKEUP )) -continue ; +hci_dev_lock (hdev); + +list_for_each_entry (b, &hdev->accept_list, list) +if (b->flags &HCI_CONN_FLAG_REMOTE_WAKEUP ) + num_entries++; + +if (!num_entries) { +hci_dev_unlock (hdev); + goto update_scan; + } + + accept_list =kmalloc_array (num_entries,sizeof (*accept_list), +GFP_KERNEL ); +if (!accept_list) { +hci_dev_unlock (hdev); +return -ENOMEM ; + } + + i =0 ; +list_for_each_entry (b, &hdev->accept_list, list) +if (b->flags &HCI_CONN_FLAG_REMOTE_WAKEUP ) +bacpy (&accept_list[i++], &b->bdaddr); + +hci_dev_unlock (hdev); -bt_dev_dbg (hdev,"Adding event filters for %pMR" , &b->bdaddr); +for (i =0 ; i < num_entries; i++) { +bt_dev_dbg (hdev,"Adding event filters for %pMR" , + &accept_list[i]); - err =hci_set_event_filter_sync (hdev,HCI_FLT_CONN_SETUP , -HCI_CONN_SETUP_ALLOW_BDADDR , - &b->bdaddr, -HCI_CONN_SETUP_AUTO_ON ); + err =hci_set_event_filter_sync (hdev,HCI_FLT_CONN_SETUP , +HCI_CONN_SETUP_ALLOW_BDADDR , + &accept_list[i], +HCI_CONN_SETUP_AUTO_ON );if (err)bt_dev_err (hdev,"Failed to set event filter for %pMR" , - &b->bdaddr); + &accept_list[i]);else scan =SCAN_PAGE ; } +kfree (accept_list); + +update_scan:if (scan && !scanning)hci_write_scan_enable_sync (hdev, scan);else if (!scan && scanning)
Signature · 1 line
2.43.0
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1138539
---Test result---
Test Summary:
CheckPatch PASS 0.74 seconds VerifyFixes PASS 0.13 seconds VerifySignedoff PASS 0.19 seconds GitLint PASS 0.32 seconds SubjectPrefix PASS 0.12 seconds BuildKernel PASS 25.43 seconds CheckAllWarning PASS 27.69 seconds CheckSparse PASS 34.47 seconds BuildKernel32 PASS 24.87 seconds CheckKernelLLVM SKIP 0.00 seconds TestRunnerSetup PASS 460.26 seconds TestRunner_l2cap-tester PASS 61.89 seconds TestRunner_iso-tester PASS 84.13 seconds TestRunner_bnep-tester PASS 18.74 seconds TestRunner_mgmt-tester FAIL 221.75 seconds TestRunner_rfcomm-tester PASS 25.75 seconds TestRunner_sco-tester PASS 31.88 seconds TestRunner_ioctl-tester PASS 27.15 seconds TestRunner_mesh-tester FAIL 25.98 seconds TestRunner_smp-tester PASS 23.62 seconds TestRunner_userchan-tester PASS 20.30 seconds TestRunner_6lowpan-tester PASS 23.37 seconds IncrementalBuild PASS 24.18 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner Output:
Total: 501, Passed: 495 (98.8%), Failed: 2, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.253 seconds LL Privacy - Unpair 1 Timed out 1.919 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 1.840 seconds Mesh - Send cancel - 2 Timed out 1.985 seconds
https://github.com/bluez/bluetooth-next/pull/523
---
Regards,
Linux Bluetooth
This patch was applied to bluetooth/bluetooth-next.git (master) by Luiz Augusto von Dentz <[email protected]>:
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master) by Luiz Augusto von Dentz <[email protected]>:
Quoted 9 lines · On Sat, 1 Aug 2026 15:05:24 +0800 you wrote:
hci_update_event_filter_sync()walkshdev->accept_listwhile sending a synchronous HCI command for each remote-wakeup device. The suspend path holdshdev->req_lock, but accept-list updates are serialized byhdev->lock. Consequently,remove_device()can free the current list entry during the controller wait.The following interleaving causes the use-after-free:
[...]
Here is the summary with links:
- [v2] Bluetooth: hci_sync: Fix accept list UAF during suspend
https://git.kernel.org/bluetooth/bluetooth-next/c/8b715ab95872
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html