diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-09-22 22:29:54 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-09-22 22:29:54 +0300 |
| commit | 3491bb7dae5c3899b52f9a2329a9d25b79c2b0fb (patch) | |
| tree | 44764a4b0c0910716f680561776e7ab1f2fee271 /net/bluetooth/hci_event.c | |
| parent | 207b45e8533f9a5b3206b6a85a984464e646b0e1 (diff) | |
| parent | 302a1f674c00dd5581ab8e493ef44767c5101aab (diff) | |
| download | linux-3491bb7dae5c3899b52f9a2329a9d25b79c2b0fb.tar.xz | |
Merge tag 'for-net-2025-09-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says:
====================
bluetooth pull request for net:
- Fix build after header cleanup
- hci_sync: Fix hci_resume_advertising_sync
- hci_event: Fix UAF in hci_conn_tx_dequeue
- hci_event: Fix UAF in hci_acl_create_conn_sync
- MGMT: Fix possible UAFs
* tag 'for-net-2025-09-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
Bluetooth: MGMT: Fix possible UAFs
Bluetooth: hci_event: Fix UAF in hci_acl_create_conn_sync
Bluetooth: hci_event: Fix UAF in hci_conn_tx_dequeue
Bluetooth: hci_sync: Fix hci_resume_advertising_sync
Bluetooth: Fix build after header cleanup
====================
Link: https://patch.msgid.link/20250922143315.3007176-1-luiz.dentz@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
| -rw-r--r-- | net/bluetooth/hci_event.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 7a2174851857..fe49e8a7969f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3087,8 +3087,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, hci_dev_lock(hdev); + /* Check for existing connection: + * + * 1. If it doesn't exist then it must be receiver/slave role. + * 2. If it does exist confirm that it is connecting/BT_CONNECT in case + * of initiator/master role since there could be a collision where + * either side is attempting to connect or something like a fuzzing + * testing is trying to play tricks to destroy the hcon object before + * it even attempts to connect (e.g. hcon->state == BT_OPEN). + */ conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); - if (!conn) { + if (!conn || + (conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) { /* In case of error status and there is no connection pending * just unlock as there is nothing to cleanup. */ @@ -4391,6 +4401,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, bt_dev_dbg(hdev, "num %d", ev->num); + hci_dev_lock(hdev); + for (i = 0; i < ev->num; i++) { struct hci_comp_pkts_info *info = &ev->handles[i]; struct hci_conn *conn; @@ -4472,6 +4484,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, } queue_work(hdev->workqueue, &hdev->tx_work); + + hci_dev_unlock(hdev); } static void hci_mode_change_evt(struct hci_dev *hdev, void *data, @@ -5634,8 +5648,18 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, */ hci_dev_clear_flag(hdev, HCI_LE_ADV); - conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr); - if (!conn) { + /* Check for existing connection: + * + * 1. If it doesn't exist then use the role to create a new object. + * 2. If it does exist confirm that it is connecting/BT_CONNECT in case + * of initiator/master role since there could be a collision where + * either side is attempting to connect or something like a fuzzing + * testing is trying to play tricks to destroy the hcon object before + * it even attempts to connect (e.g. hcon->state == BT_OPEN). + */ + conn = hci_conn_hash_lookup_role(hdev, LE_LINK, role, bdaddr); + if (!conn || + (conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) { /* In case of error status and there is no connection pending * just unlock as there is nothing to cleanup. */ |
