@@ -3087,8 +3087,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
3087
3087
3088
3088
hci_dev_lock (hdev );
3089
3089
3090
+ /* Check for existing connection:
3091
+ *
3092
+ * 1. If it doesn't exist then it must be receiver/slave role.
3093
+ * 2. If it does exist confirm that it is connecting/BT_CONNECT in case
3094
+ * of initiator/master role since there could be a collision where
3095
+ * either side is attempting to connect or something like a fuzzing
3096
+ * testing is trying to play tricks to destroy the hcon object before
3097
+ * it even attempts to connect (e.g. hcon->state == BT_OPEN).
3098
+ */
3090
3099
conn = hci_conn_hash_lookup_ba (hdev , ev -> link_type , & ev -> bdaddr );
3091
- if (!conn ) {
3100
+ if (!conn ||
3101
+ (conn -> role == HCI_ROLE_MASTER && conn -> state != BT_CONNECT )) {
3092
3102
/* In case of error status and there is no connection pending
3093
3103
* just unlock as there is nothing to cleanup.
3094
3104
*/
@@ -4391,6 +4401,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
4391
4401
4392
4402
bt_dev_dbg (hdev , "num %d" , ev -> num );
4393
4403
4404
+ hci_dev_lock (hdev );
4405
+
4394
4406
for (i = 0 ; i < ev -> num ; i ++ ) {
4395
4407
struct hci_comp_pkts_info * info = & ev -> handles [i ];
4396
4408
struct hci_conn * conn ;
@@ -4472,6 +4484,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
4472
4484
}
4473
4485
4474
4486
queue_work (hdev -> workqueue , & hdev -> tx_work );
4487
+
4488
+ hci_dev_unlock (hdev );
4475
4489
}
4476
4490
4477
4491
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,
5634
5648
*/
5635
5649
hci_dev_clear_flag (hdev , HCI_LE_ADV );
5636
5650
5637
- conn = hci_conn_hash_lookup_ba (hdev , LE_LINK , bdaddr );
5638
- if (!conn ) {
5651
+ /* Check for existing connection:
5652
+ *
5653
+ * 1. If it doesn't exist then use the role to create a new object.
5654
+ * 2. If it does exist confirm that it is connecting/BT_CONNECT in case
5655
+ * of initiator/master role since there could be a collision where
5656
+ * either side is attempting to connect or something like a fuzzing
5657
+ * testing is trying to play tricks to destroy the hcon object before
5658
+ * it even attempts to connect (e.g. hcon->state == BT_OPEN).
5659
+ */
5660
+ conn = hci_conn_hash_lookup_role (hdev , LE_LINK , role , bdaddr );
5661
+ if (!conn ||
5662
+ (conn -> role == HCI_ROLE_MASTER && conn -> state != BT_CONNECT )) {
5639
5663
/* In case of error status and there is no connection pending
5640
5664
* just unlock as there is nothing to cleanup.
5641
5665
*/
0 commit comments