summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorCen Zhang <zzzccc427@163.com>2025-09-29 05:30:17 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-11-13 15:33:58 -0500
commitae76cf6c2c842944c6514c57df54d728f1916553 (patch)
tree221cdedf7bdd3fffacd585b104b9e54942a4cf43 /net
parent2ce1de32e05445d77fc056f6ff8339cfb78a5f84 (diff)
downloadlinux-ae76cf6c2c842944c6514c57df54d728f1916553.tar.gz
linux-ae76cf6c2c842944c6514c57df54d728f1916553.tar.bz2
linux-ae76cf6c2c842944c6514c57df54d728f1916553.zip
Bluetooth: hci_sync: fix race in hci_cmd_sync_dequeue_once
[ Upstream commit 09b0cd1297b4dbfe736aeaa0ceeab2265f47f772 ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_sync.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 853acfa8e943..c08e46ee70b2 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -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;
}