Bluetooth: Fix race between hci_register_dev() and hci_dev_open()
If hci_dev_open() is called after hci_register_dev() added the device to the hci_dev_list but before the workqueue are created we could run into a NULL pointer dereference (see below). This bug is very unlikely to happen, systems using bluetoothd to manage their bluetooth devices will never see this happen. BUG: unable to handle kernel NULL pointer dereference 0100 IP: [<ffffffff81077502>] __queue_work+0x32/0x3d0 (...) Call Trace: [<ffffffff81077be5>] queue_work_on+0x45/0x50 [<ffffffffa016e8ff>] hci_req_run+0xbf/0xf0 [bluetooth] [<ffffffffa01709b0>] ? hci_init2_req+0x720/0x720 [bluetooth] [<ffffffffa016ea06>] __hci_req_sync+0xd6/0x1c0 [bluetooth] [<ffffffff8108ee10>] ? try_to_wake_up+0x2b0/0x2b0 [<ffffffff8150e3f0>] ? usb_autopm_put_interface+0x30/0x40 [<ffffffffa016fad5>] hci_dev_open+0x275/0x2e0 [bluetooth] [<ffffffffa0182752>] hci_sock_ioctl+0x1f2/0x3f0 [bluetooth] [<ffffffff815c6050>] sock_do_ioctl+0x30/0x70 [<ffffffff815c75f9>] sock_ioctl+0x79/0x2f0 [<ffffffff811a8046>] do_vfs_ioctl+0x96/0x560 [<ffffffff811a85a1>] SyS_ioctl+0x91/0xb0 [<ffffffff816d989d>] system_call_fastpath+0x1a/0x1f Reported-by: Sedat Dilek <sedat.dilek@gmail.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This commit is contained in:
Родитель
1ebd0b21ab
Коммит
fcee337704
|
@ -2207,10 +2207,6 @@ int hci_register_dev(struct hci_dev *hdev)
|
|||
|
||||
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
|
||||
|
||||
write_lock(&hci_dev_list_lock);
|
||||
list_add(&hdev->list, &hci_dev_list);
|
||||
write_unlock(&hci_dev_list_lock);
|
||||
|
||||
hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
|
||||
WQ_MEM_RECLAIM, 1);
|
||||
if (!hdev->workqueue) {
|
||||
|
@ -2246,6 +2242,10 @@ int hci_register_dev(struct hci_dev *hdev)
|
|||
if (hdev->dev_type != HCI_AMP)
|
||||
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
|
||||
|
||||
write_lock(&hci_dev_list_lock);
|
||||
list_add(&hdev->list, &hci_dev_list);
|
||||
write_unlock(&hci_dev_list_lock);
|
||||
|
||||
hci_notify(hdev, HCI_DEV_REG);
|
||||
hci_dev_hold(hdev);
|
||||
|
||||
|
@ -2258,9 +2258,6 @@ err_wqueue:
|
|||
destroy_workqueue(hdev->req_workqueue);
|
||||
err:
|
||||
ida_simple_remove(&hci_index_ida, hdev->id);
|
||||
write_lock(&hci_dev_list_lock);
|
||||
list_del(&hdev->list);
|
||||
write_unlock(&hci_dev_list_lock);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче