| @@ -2834,7 +2834,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) · 2833 unmodified lines |
| 2834 | 2834 | bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 2835 | 2835 | |
| 2836 | 2836 | /* All connection failure handling is taken care of by the |
| 2837 | | − * hci_le_conn_failed function which is triggered by the HCI |
| 2837 | + * hci_conn_failed function which is triggered by the HCI |
| 2838 | 2838 | * request completion callbacks used for connecting. |
| 2839 | 2839 | */ |
| 2840 | 2840 | if (status) |
| @@ -2859,7 +2859,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) · 18 unmodified lines |
| 2859 | 2859 | bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 2860 | 2860 | |
| 2861 | 2861 | /* All connection failure handling is taken care of by the |
| 2862 | | − * hci_le_conn_failed function which is triggered by the HCI |
| 2862 | + * hci_conn_failed function which is triggered by the HCI |
| 2863 | 2863 | * request completion callbacks used for connecting. |
| 2864 | 2864 | */ |
| 2865 | 2865 | if (status) |
| @@ -3067,18 +3067,20 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 201 unmodified lines |
| 3067 | 3067 | { |
| 3068 | 3068 | struct hci_ev_conn_complete *ev = data; |
| 3069 | 3069 | struct hci_conn *conn; |
| 3070 | + u8 status = ev->status; |
| 3070 | 3071 | |
| 3071 | | − if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) { |
| 3072 | | − bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for invalid handle"); |
| 3073 | | − return; |
| 3074 | | − } |
| 3075 | | − |
| 3076 | | − bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); |
| 3072 | + bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 3077 | 3073 | |
| 3078 | 3074 | hci_dev_lock(hdev); |
| 3079 | 3075 | |
| 3080 | 3076 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); |
| 3081 | 3077 | if (!conn) { |
| 3078 | + /* In case of error status and there is no connection pending |
| 3079 | + * just unlock as there is nothing to cleanup. |
| 3080 | + */ |
| 3081 | + if (ev->status) |
| 3082 | + goto unlock; |
| 3083 | + |
| 3082 | 3084 | /* Connection may not exist if auto-connected. Check the bredr |
| 3083 | 3085 | * allowlist to see if this device is allowed to auto connect. |
| 3084 | 3086 | * If link is an ACL type, create a connection class |
| @@ -3122,8 +3124,14 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 37 unmodified lines |
| 3122 | 3124 | goto unlock; |
| 3123 | 3125 | } |
| 3124 | 3126 | |
| 3125 | | − if (!ev->status) { |
| 3127 | + if (!status) { |
| 3126 | 3128 | conn->handle = __le16_to_cpu(ev->handle); |
| 3129 | + if (conn->handle > HCI_CONN_HANDLE_MAX) { |
| 3130 | + bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", |
| 3131 | + conn->handle, HCI_CONN_HANDLE_MAX); |
| 3132 | + status = HCI_ERROR_INVALID_PARAMETERS; |
| 3133 | + goto done; |
| 3134 | + } |
| 3127 | 3135 | |
| 3128 | 3136 | if (conn->type == ACL_LINK) { |
| 3129 | 3137 | conn->state = BT_CONFIG; |
| @@ -3164,19 +3172,14 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 34 unmodified lines |
| 3164 | 3172 | hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), |
| 3165 | 3173 | &cp); |
| 3166 | 3174 | } |
| 3167 | | − } else { |
| 3168 | | − conn->state = BT_CLOSED; |
| 3169 | | − if (conn->type == ACL_LINK) |
| 3170 | | − mgmt_connect_failed(hdev, &conn->dst, conn->type, |
| 3171 | | − conn->dst_type, ev->status); |
| 3172 | 3175 | } |
| 3173 | 3176 | |
| 3174 | 3177 | if (conn->type == ACL_LINK) |
| 3175 | 3178 | hci_sco_setup(conn, ev->status); |
| 3176 | 3179 | |
| 3177 | | − if (ev->status) { |
| 3178 | | − hci_connect_cfm(conn, ev->status); |
| 3179 | | − hci_conn_del(conn); |
| 3180 | +done: |
| 3181 | + if (status) { |
| 3182 | + hci_conn_failed(conn, status); |
| 3180 | 3183 | } else if (ev->link_type == SCO_LINK) { |
| 3181 | 3184 | switch (conn->setting & SCO_AIRMODE_MASK) { |
| 3182 | 3185 | case SCO_AIRMODE_CVSD: |
| @@ -3185,7 +3188,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 2 unmodified lines |
| 3185 | 3188 | break; |
| 3186 | 3189 | } |
| 3187 | 3190 | |
| 3188 | | − hci_connect_cfm(conn, ev->status); |
| 3191 | + hci_connect_cfm(conn, status); |
| 3189 | 3192 | } |
| 3190 | 3193 | |
| 3191 | 3194 | unlock: |
| @@ -4676,6 +4679,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 1484 unmodified lines |
| 4676 | 4679 | { |
| 4677 | 4680 | struct hci_ev_sync_conn_complete *ev = data; |
| 4678 | 4681 | struct hci_conn *conn; |
| 4682 | + u8 status = ev->status; |
| 4679 | 4683 | |
| 4680 | 4684 | switch (ev->link_type) { |
| 4681 | 4685 | case SCO_LINK: |
| @@ -4690,12 +4694,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 8 unmodified lines |
| 4690 | 4694 | return; |
| 4691 | 4695 | } |
| 4692 | 4696 | |
| 4693 | | − if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) { |
| 4694 | | − bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete for invalid handle"); |
| 4695 | | − return; |
| 4696 | | − } |
| 4697 | | − |
| 4698 | | − bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); |
| 4697 | + bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 4699 | 4698 | |
| 4700 | 4699 | hci_dev_lock(hdev); |
| 4701 | 4700 | |
| @@ -4729,9 +4728,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 27 unmodified lines |
| 4729 | 4728 | goto unlock; |
| 4730 | 4729 | } |
| 4731 | 4730 | |
| 4732 | | − switch (ev->status) { |
| 4731 | + switch (status) { |
| 4733 | 4732 | case 0x00: |
| 4734 | 4733 | conn->handle = __le16_to_cpu(ev->handle); |
| 4734 | + if (conn->handle > HCI_CONN_HANDLE_MAX) { |
| 4735 | + bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", |
| 4736 | + conn->handle, HCI_CONN_HANDLE_MAX); |
| 4737 | + status = HCI_ERROR_INVALID_PARAMETERS; |
| 4738 | + conn->state = BT_CLOSED; |
| 4739 | + break; |
| 4740 | + } |
| 4741 | + |
| 4735 | 4742 | conn->state = BT_CONNECTED; |
| 4736 | 4743 | conn->type = ev->link_type; |
| 4737 | 4744 | |
| @@ -4775,8 +4782,8 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 37 unmodified lines |
| 4775 | 4782 | } |
| 4776 | 4783 | } |
| 4777 | 4784 | |
| 4778 | | − hci_connect_cfm(conn, ev->status); |
| 4779 | | − if (ev->status) |
| 4785 | + hci_connect_cfm(conn, status); |
| 4786 | + if (status) |
| 4780 | 4787 | hci_conn_del(conn); |
| 4781 | 4788 | |
| 4782 | 4789 | unlock: |
| @@ -5527,11 +5534,6 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 744 unmodified lines |
| 5527 | 5534 | struct smp_irk *irk; |
| 5528 | 5535 | u8 addr_type; |
| 5529 | 5536 | |
| 5530 | | − if (handle > HCI_CONN_HANDLE_MAX) { |
| 5531 | | − bt_dev_err(hdev, "Ignoring HCI_LE_Connection_Complete for invalid handle"); |
| 5532 | | − return; |
| 5533 | | − } |
| 5534 | | − |
| 5535 | 5537 | hci_dev_lock(hdev); |
| 5536 | 5538 | |
| 5537 | 5539 | /* All controllers implicitly stop advertising in the event of a |
| @@ -5541,6 +5543,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 3 unmodified lines |
| 5541 | 5543 | |
| 5542 | 5544 | conn = hci_lookup_le_connect(hdev); |
| 5543 | 5545 | if (!conn) { |
| 5546 | + /* In case of error status and there is no connection pending |
| 5547 | + * just unlock as there is nothing to cleanup. |
| 5548 | + */ |
| 5549 | + if (status) |
| 5550 | + goto unlock; |
| 5551 | + |
| 5544 | 5552 | conn = hci_conn_add(hdev, LE_LINK, bdaddr, role); |
| 5545 | 5553 | if (!conn) { |
| 5546 | 5554 | bt_dev_err(hdev, "no memory for new connection"); |
| @@ -5603,8 +5611,14 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 56 unmodified lines |
| 5603 | 5611 | |
| 5604 | 5612 | conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL); |
| 5605 | 5613 | |
| 5614 | + if (handle > HCI_CONN_HANDLE_MAX) { |
| 5615 | + bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", handle, |
| 5616 | + HCI_CONN_HANDLE_MAX); |
| 5617 | + status = HCI_ERROR_INVALID_PARAMETERS; |
| 5618 | + } |
| 5619 | + |
| 5606 | 5620 | if (status) { |
| 5607 | | − hci_le_conn_failed(conn, status); |
| 5621 | + hci_conn_failed(conn, status); |
| 5608 | 5622 | goto unlock; |
| 5609 | 5623 | } |
| 5610 | 5624 | |