@@ -3087,8 +3087,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30873087
30883088 hci_dev_lock (hdev );
30893089
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+ */
30903099 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 )) {
30923102 /* In case of error status and there is no connection pending
30933103 * just unlock as there is nothing to cleanup.
30943104 */
@@ -4391,6 +4401,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
43914401
43924402 bt_dev_dbg (hdev , "num %d" , ev -> num );
43934403
4404+ hci_dev_lock (hdev );
4405+
43944406 for (i = 0 ; i < ev -> num ; i ++ ) {
43954407 struct hci_comp_pkts_info * info = & ev -> handles [i ];
43964408 struct hci_conn * conn ;
@@ -4472,6 +4484,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
44724484 }
44734485
44744486 queue_work (hdev -> workqueue , & hdev -> tx_work );
4487+
4488+ hci_dev_unlock (hdev );
44754489}
44764490
44774491static 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,
56345648 */
56355649 hci_dev_clear_flag (hdev , HCI_LE_ADV );
56365650
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 )) {
56395663 /* In case of error status and there is no connection pending
56405664 * just unlock as there is nothing to cleanup.
56415665 */
0 commit comments