Skip to content

Commit 2449007

Browse files
Ying HsuVudentz
authored andcommitted
Bluetooth: Avoid potential use-after-free in hci_error_reset
While handling the HCI_EV_HARDWARE_ERROR event, if the underlying BT controller is not responding, the GPIO reset mechanism would free the hci_dev and lead to a use-after-free in hci_error_reset. Here's the call trace observed on a ChromeOS device with Intel AX201: queue_work_on+0x3e/0x6c __hci_cmd_sync_sk+0x2ee/0x4c0 [bluetooth <HASH:3b4a6>] ? init_wait_entry+0x31/0x31 __hci_cmd_sync+0x16/0x20 [bluetooth <HASH:3b4a 6>] hci_error_reset+0x4f/0xa4 [bluetooth <HASH:3b4a 6>] process_one_work+0x1d8/0x33f worker_thread+0x21b/0x373 kthread+0x13a/0x152 ? pr_cont_work+0x54/0x54 ? kthread_blkcg+0x31/0x31 ret_from_fork+0x1f/0x30 This patch holds the reference count on the hci_dev while processing a HCI_EV_HARDWARE_ERROR event to avoid potential crash. Fixes: c7741d1 ("Bluetooth: Perform a power cycle when receiving hardware error event") Signed-off-by: Ying Hsu <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 6b3899b commit 2449007

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

net/bluetooth/hci_core.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,17 +1049,18 @@ static void hci_error_reset(struct work_struct *work)
10491049
{
10501050
struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
10511051

1052+
hci_dev_hold(hdev);
10521053
BT_DBG("%s", hdev->name);
10531054

10541055
if (hdev->hw_error)
10551056
hdev->hw_error(hdev, hdev->hw_error_code);
10561057
else
10571058
bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
10581059

1059-
if (hci_dev_do_close(hdev))
1060-
return;
1060+
if (!hci_dev_do_close(hdev))
1061+
hci_dev_do_open(hdev);
10611062

1062-
hci_dev_do_open(hdev);
1063+
hci_dev_put(hdev);
10631064
}
10641065

10651066
void hci_uuids_clear(struct hci_dev *hdev)

0 commit comments

Comments
 (0)