Bluetooth: hci_core: fix list_for_each_entry_rcu usage

[ Upstream commit 308a3a8ce8ea41b26c46169f3263e50f5997c28e ]

Releasing + re-acquiring RCU lock inside list_for_each_entry_rcu() loop
body is not correct.

Fix by taking the update-side hdev->lock instead.

Fixes: c7eaf80bfb ("Bluetooth: Fix hci_link_tx_to RCU lock usage")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Pauli Virtanen
2025-05-31 18:24:58 +03:00
committed by Greg Kroah-Hartman
parent 21f071261f
commit 6edb171845

View File

@@ -3380,23 +3380,18 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
bt_dev_err(hdev, "link tx timeout"); bt_dev_err(hdev, "link tx timeout");
rcu_read_lock(); hci_dev_lock(hdev);
/* Kill stalled connections */ /* Kill stalled connections */
list_for_each_entry_rcu(c, &h->list, list) { list_for_each_entry(c, &h->list, list) {
if (c->type == type && c->sent) { if (c->type == type && c->sent) {
bt_dev_err(hdev, "killing stalled connection %pMR", bt_dev_err(hdev, "killing stalled connection %pMR",
&c->dst); &c->dst);
/* hci_disconnect might sleep, so, we have to release
* the RCU read lock before calling it.
*/
rcu_read_unlock();
hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
rcu_read_lock();
} }
} }
rcu_read_unlock(); hci_dev_unlock(hdev);
} }
static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,