summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Ma <linma@zju.edu.cn>2021-04-12 19:17:57 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-06-03 08:22:09 +0200
commita7dc1c981038bbd5f7379148d7fd8821d2a7b9ae (patch)
tree998c3454a3bfae197b4a273c0a526d8176677a67
parent7dba431185d9e07be7b1d125b3290c5ee4d80525 (diff)
downloadlinux-a7dc1c981038bbd5f7379148d7fd8821d2a7b9ae.tar.gz
linux-a7dc1c981038bbd5f7379148d7fd8821d2a7b9ae.tar.bz2
linux-a7dc1c981038bbd5f7379148d7fd8821d2a7b9ae.zip
bluetooth: eliminate the potential race condition when removing the HCI controller
commit e2cb6b891ad2b8caa9131e3be70f45243df82a80 upstream. There is a possible race condition vulnerability between issuing a HCI command and removing the cont. Specifically, functions hci_req_sync() and hci_dev_do_close() can race each other like below: thread-A in hci_req_sync() | thread-B in hci_dev_do_close() | hci_req_sync_lock(hdev); test_bit(HCI_UP, &hdev->flags); | ... | test_and_clear_bit(HCI_UP, &hdev->flags) hci_req_sync_lock(hdev); | | In this commit we alter the sequence in function hci_req_sync(). Hence, the thread-A cannot issue th. Signed-off-by: Lin Ma <linma@zju.edu.cn> Cc: Marcel Holtmann <marcel@holtmann.org> Fixes: 7c6a329e4447 ("[Bluetooth] Fix regression from using default link policy") [iwamatsu: adjust filename, arguments of __hci_req_sync(). CVE-2021-32399] Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/bluetooth/hci_core.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cc905a4e5732..81a81b9a3c7d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -371,12 +371,17 @@ static int hci_req_sync(struct hci_dev *hdev,
{
int ret;
- if (!test_bit(HCI_UP, &hdev->flags))
- return -ENETDOWN;
-
/* Serialize all requests */
hci_req_lock(hdev);
- ret = __hci_req_sync(hdev, req, opt, timeout);
+ /* check the state after obtaing the lock to protect the HCI_UP
+ * against any races from hci_dev_do_close when the controller
+ * gets removed.
+ */
+ if (test_bit(HCI_UP, &hdev->flags))
+ ret = __hci_req_sync(hdev, req, opt, timeout);
+ else
+ ret = -ENETDOWN;
+
hci_req_unlock(hdev);
return ret;