]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: hci_sync: fix race in hci_cmd_sync_dequeue_once
authorCen Zhang <zzzccc427@163.com>
Mon, 29 Sep 2025 05:30:17 +0000 (05:30 +0000)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 24 Oct 2025 14:20:15 +0000 (10:20 -0400)
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>
net/bluetooth/hci_sync.c

index eefdb6134ca53b96e9fe9c17bec2b21c56977af0..d160e5e1fe8ab31db02dd383276cb07289ddaa61 100644 (file)
@@ -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)
+       mutex_lock(&hdev->cmd_sync_work_lock);
+
+       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);
+       _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
+
+       mutex_unlock(&hdev->cmd_sync_work_lock);
 
        return true;
 }