History

Merge tag 'for-net-2022-04-27' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth

Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - Fix regression causing some HCI events to be discarded when they shouldn't. * tag 'for-net-2022-04-27' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_sync: Cleanup hci_conn if it cannot be aborted Bluetooth: hci_event: Fix creating hci_conn object on error status Bluetooth: hci_event: Fix checking for invalid handle on error status ====================

Paolo Abeni committed 4 years ago

Commit febb2d22 parents d2b52ec 9b3628d5 files · +83 −43Browse files

Unified · Split

5 files
  1. include/net/bluetooth/hci.h +1 −0
  2. include/net/bluetooth/hci_core.h +1 −1
  3. net/bluetooth/hci_conn.c +24 −8
  4. net/bluetooth/hci_event.c +47 −33
  5. net/bluetooth/hci_sync.c +10 −1
include/net/bluetooth/hci.h+1−0
@@ -578,6 +578,7 @@ enum { · 577 unmodified lines
578578 #define HCI_ERROR_CONNECTION_TIMEOUT 0x08
579579 #define HCI_ERROR_REJ_LIMITED_RESOURCES 0x0d
580580 #define HCI_ERROR_REJ_BAD_ADDR 0x0f
581+#define HCI_ERROR_INVALID_PARAMETERS 0x12
581582 #define HCI_ERROR_REMOTE_USER_TERM 0x13
582583 #define HCI_ERROR_REMOTE_LOW_RESOURCES 0x14
583584 #define HCI_ERROR_REMOTE_POWER_OFF 0x15
include/net/bluetooth/hci_core.h+1−1
@@ -1156,7 +1156,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); · 1155 unmodified lines
11561156
11571157 void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
11581158
1159−void hci_le_conn_failed(struct hci_conn *conn, u8 status);
1159+void hci_conn_failed(struct hci_conn *conn, u8 status);
11601160
11611161 /*
11621162 * hci_conn_get() and hci_conn_put() are used to control the life-time of an
net/bluetooth/hci_conn.c+24−8
@@ -670,7 +670,7 @@ static void le_conn_timeout(struct work_struct *work) · 669 unmodified lines
670670 /* Disable LE Advertising */
671671 le_disable_advertising(hdev);
672672 hci_dev_lock(hdev);
673− hci_le_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
673+ hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
674674 hci_dev_unlock(hdev);
675675 return;
676676 }
@@ -873,7 +873,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type) · 196 unmodified lines
873873 EXPORT_SYMBOL(hci_get_route);
874874
875875 /* This function requires the caller holds hdev->lock */
876−void hci_le_conn_failed(struct hci_conn *conn, u8 status)
876+static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
877877 {
878878 struct hci_dev *hdev = conn->hdev;
879879 struct hci_conn_params *params;
@@ -886,8 +886,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 6 unmodified lines
886886 params->conn = NULL;
887887 }
888888
889− conn->state = BT_CLOSED;
890−
891889 /* If the status indicates successful cancellation of
892890 * the attempt (i.e. Unknown Connection Id) there's no point of
893891 * notifying failure since we'll go back to keep trying to
@@ -899,10 +897,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 5 unmodified lines
899897 mgmt_connect_failed(hdev, &conn->dst, conn->type,
900898 conn->dst_type, status);
901899
902− hci_connect_cfm(conn, status);
903−
904− hci_conn_del(conn);
905−
906900 /* Since we may have temporarily stopped the background scanning in
907901 * favor of connection establishment, we should restart it.
908902 */
@@ -914,6 +908,28 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 5 unmodified lines
914908 hci_enable_advertising(hdev);
915909 }
916910
911+/* This function requires the caller holds hdev->lock */
912+void hci_conn_failed(struct hci_conn *conn, u8 status)
913+{
914+ struct hci_dev *hdev = conn->hdev;
915+
916+ bt_dev_dbg(hdev, "status 0x%2.2x", status);
917+
918+ switch (conn->type) {
919+ case LE_LINK:
920+ hci_le_conn_failed(conn, status);
921+ break;
922+ case ACL_LINK:
923+ mgmt_connect_failed(hdev, &conn->dst, conn->type,
924+ conn->dst_type, status);
925+ break;
926+ }
927+
928+ conn->state = BT_CLOSED;
929+ hci_connect_cfm(conn, status);
930+ hci_conn_del(conn);
931+}
932+
917933 static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
918934 {
919935 struct hci_conn *conn = data;
net/bluetooth/hci_event.c+47−33
@@ -2834,7 +2834,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) · 2833 unmodified lines
28342834 bt_dev_dbg(hdev, "status 0x%2.2x", status);
28352835
28362836 /* 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
28382838 * request completion callbacks used for connecting.
28392839 */
28402840 if (status)
@@ -2859,7 +2859,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) · 18 unmodified lines
28592859 bt_dev_dbg(hdev, "status 0x%2.2x", status);
28602860
28612861 /* 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
28632863 * request completion callbacks used for connecting.
28642864 */
28652865 if (status)
@@ -3067,18 +3067,20 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 201 unmodified lines
30673067 {
30683068 struct hci_ev_conn_complete *ev = data;
30693069 struct hci_conn *conn;
3070+ u8 status = ev->status;
30703071
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);
30773073
30783074 hci_dev_lock(hdev);
30793075
30803076 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
30813077 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+
30823084 /* Connection may not exist if auto-connected. Check the bredr
30833085 * allowlist to see if this device is allowed to auto connect.
30843086 * 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
31223124 goto unlock;
31233125 }
31243126
3125− if (!ev->status) {
3127+ if (!status) {
31263128 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+ }
31273135
31283136 if (conn->type == ACL_LINK) {
31293137 conn->state = BT_CONFIG;
@@ -3164,19 +3172,14 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 34 unmodified lines
31643172 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
31653173 &cp);
31663174 }
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);
31723175 }
31733176
31743177 if (conn->type == ACL_LINK)
31753178 hci_sco_setup(conn, ev->status);
31763179
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);
31803183 } else if (ev->link_type == SCO_LINK) {
31813184 switch (conn->setting & SCO_AIRMODE_MASK) {
31823185 case SCO_AIRMODE_CVSD:
@@ -3185,7 +3188,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 2 unmodified lines
31853188 break;
31863189 }
31873190
3188− hci_connect_cfm(conn, ev->status);
3191+ hci_connect_cfm(conn, status);
31893192 }
31903193
31913194 unlock:
@@ -4676,6 +4679,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 1484 unmodified lines
46764679 {
46774680 struct hci_ev_sync_conn_complete *ev = data;
46784681 struct hci_conn *conn;
4682+ u8 status = ev->status;
46794683
46804684 switch (ev->link_type) {
46814685 case SCO_LINK:
@@ -4690,12 +4694,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 8 unmodified lines
46904694 return;
46914695 }
46924696
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);
46994698
47004699 hci_dev_lock(hdev);
47014700
@@ -4729,9 +4728,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 27 unmodified lines
47294728 goto unlock;
47304729 }
47314730
4732− switch (ev->status) {
4731+ switch (status) {
47334732 case 0x00:
47344733 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+
47354742 conn->state = BT_CONNECTED;
47364743 conn->type = ev->link_type;
47374744
@@ -4775,8 +4782,8 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, · 37 unmodified lines
47754782 }
47764783 }
47774784
4778− hci_connect_cfm(conn, ev->status);
4779− if (ev->status)
4785+ hci_connect_cfm(conn, status);
4786+ if (status)
47804787 hci_conn_del(conn);
47814788
47824789 unlock:
@@ -5527,11 +5534,6 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 744 unmodified lines
55275534 struct smp_irk *irk;
55285535 u8 addr_type;
55295536
5530− if (handle > HCI_CONN_HANDLE_MAX) {
5531− bt_dev_err(hdev, "Ignoring HCI_LE_Connection_Complete for invalid handle");
5532− return;
5533− }
5534−
55355537 hci_dev_lock(hdev);
55365538
55375539 /* 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
55415543
55425544 conn = hci_lookup_le_connect(hdev);
55435545 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+
55445552 conn = hci_conn_add(hdev, LE_LINK, bdaddr, role);
55455553 if (!conn) {
55465554 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
56035611
56045612 conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
56055613
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+
56065620 if (status) {
5607− hci_le_conn_failed(conn, status);
5621+ hci_conn_failed(conn, status);
56085622 goto unlock;
56095623 }
56105624
net/bluetooth/hci_sync.c+10−1
@@ -4408,12 +4408,21 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, · 4407 unmodified lines
44084408 static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
44094409 u8 reason)
44104410 {
4411+ int err;
4412+
44114413 switch (conn->state) {
44124414 case BT_CONNECTED:
44134415 case BT_CONFIG:
44144416 return hci_disconnect_sync(hdev, conn, reason);
44154417 case BT_CONNECT:
4416− return hci_connect_cancel_sync(hdev, conn);
4418+ err = hci_connect_cancel_sync(hdev, conn);
4419+ /* Cleanup hci_conn object if it cannot be cancelled as it
4420+ * likelly means the controller and host stack are out of sync.
4421+ */
4422+ if (err)
4423+ hci_conn_failed(conn, err);
4424+
4425+ return err;
44174426 case BT_CONNECT2:
44184427 return hci_reject_conn_sync(hdev, conn, reason);
44194428 default:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t