Bluetooth: hci_sync: fix race in hci_cmd_sync_dequeue_once

hci_cmd_sync_dequeue_once() does lookup and then cancel
the entry under two separate lock sections. Meanwhile,
hci_cmd_sync_work() can also delete the same entry,
leading to double list_del() and "UAF".

Fix this by holding cmd_sync_work_lock across both
lookup and cancel, so that the entry cannot be removed
concurrently.

Fixes: 505ea2b29592 ("Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue")
Reported-by: Cen Zhang <zzzccc427@163.com>
Signed-off-by: Cen Zhang <zzzccc427@163.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Cen Zhang 2025-09-29 05:30:17 +00:00 committed by Luiz Augusto von Dentz
parent 1ab6658174
commit 09b0cd1297

@ -863,11 +863,17 @@ bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
{
struct hci_cmd_sync_work_entry *entry;
entry = hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
if (!entry)
return false;
mutex_lock(&hdev->cmd_sync_work_lock);
hci_cmd_sync_cancel_entry(hdev, entry);
entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
if (!entry) {
mutex_unlock(&hdev->cmd_sync_work_lock);
return false;
}
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
mutex_unlock(&hdev->cmd_sync_work_lock);
return true;
}