Skip to content

Commit c86cc5a

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: hci_event: Fix checking for invalid handle on error status
Commit d5ebaa7 introduces checks for handle range (e.g HCI_CONN_HANDLE_MAX) but controllers like Intel AX200 don't seem to respect the valid range int case of error status: > HCI Event: Connect Complete (0x03) plen 11 Status: Page Timeout (0x04) Handle: 65535 Address: 94:DB:56:XX:XX:XX (Sony Home Entertainment& Sound Products Inc) Link type: ACL (0x01) Encryption: Disabled (0x00) [1644965.827560] Bluetooth: hci0: Ignoring HCI_Connection_Complete for invalid handle Because of it is impossible to cleanup the connections properly since the stack would attempt to cancel the connection which is no longer in progress causing the following trace: < HCI Command: Create Connection Cancel (0x01|0x0008) plen 6 Address: 94:DB:56:XX:XX:XX (Sony Home Entertainment& Sound Products Inc) = bluetoothd: src/profile.c:record_cb() Unable to get Hands-Free Voice gateway SDP record: Connection timed out > HCI Event: Command Complete (0x0e) plen 10 Create Connection Cancel (0x01|0x0008) ncmd 1 Status: Unknown Connection Identifier (0x02) Address: 94:DB:56:XX:XX:XX (Sony Home Entertainment& Sound Products Inc) < HCI Command: Create Connection Cancel (0x01|0x0008) plen 6 Address: 94:DB:56:XX:XX:XX (Sony Home Entertainment& Sound Products Inc) Fixes: d5ebaa7 ("Bluetooth: hci_event: Ignore multiple conn complete events") Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent acb16b3 commit c86cc5a

File tree

2 files changed

+37
-29
lines changed

2 files changed

+37
-29
lines changed

include/net/bluetooth/hci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ enum {
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

net/bluetooth/hci_event.c

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,13 +3067,9 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
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

@@ -3122,8 +3118,14 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31223118
goto unlock;
31233119
}
31243120

3125-
if (!ev->status) {
3121+
if (!status) {
31263122
conn->handle = __le16_to_cpu(ev->handle);
3123+
if (conn->handle > HCI_CONN_HANDLE_MAX) {
3124+
bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
3125+
conn->handle, HCI_CONN_HANDLE_MAX);
3126+
status = HCI_ERROR_INVALID_PARAMETERS;
3127+
goto done;
3128+
}
31273129

31283130
if (conn->type == ACL_LINK) {
31293131
conn->state = BT_CONFIG;
@@ -3164,18 +3166,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31643166
hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
31653167
&cp);
31663168
}
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);
31723169
}
31733170

31743171
if (conn->type == ACL_LINK)
31753172
hci_sco_setup(conn, ev->status);
31763173

3177-
if (ev->status) {
3178-
hci_connect_cfm(conn, ev->status);
3174+
done:
3175+
if (status) {
3176+
conn->state = BT_CLOSED;
3177+
if (conn->type == ACL_LINK)
3178+
mgmt_connect_failed(hdev, &conn->dst, conn->type,
3179+
conn->dst_type, status);
3180+
hci_connect_cfm(conn, status);
31793181
hci_conn_del(conn);
31803182
} else if (ev->link_type == SCO_LINK) {
31813183
switch (conn->setting & SCO_AIRMODE_MASK) {
@@ -3185,7 +3187,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31853187
break;
31863188
}
31873189

3188-
hci_connect_cfm(conn, ev->status);
3190+
hci_connect_cfm(conn, status);
31893191
}
31903192

31913193
unlock:
@@ -4676,6 +4678,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
46764678
{
46774679
struct hci_ev_sync_conn_complete *ev = data;
46784680
struct hci_conn *conn;
4681+
u8 status = ev->status;
46794682

46804683
switch (ev->link_type) {
46814684
case SCO_LINK:
@@ -4690,12 +4693,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
46904693
return;
46914694
}
46924695

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);
4696+
bt_dev_dbg(hdev, "status 0x%2.2x", status);
46994697

47004698
hci_dev_lock(hdev);
47014699

@@ -4729,9 +4727,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
47294727
goto unlock;
47304728
}
47314729

4732-
switch (ev->status) {
4730+
switch (status) {
47334731
case 0x00:
47344732
conn->handle = __le16_to_cpu(ev->handle);
4733+
if (conn->handle > HCI_CONN_HANDLE_MAX) {
4734+
bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
4735+
conn->handle, HCI_CONN_HANDLE_MAX);
4736+
status = HCI_ERROR_INVALID_PARAMETERS;
4737+
conn->state = BT_CLOSED;
4738+
break;
4739+
}
4740+
47354741
conn->state = BT_CONNECTED;
47364742
conn->type = ev->link_type;
47374743

@@ -4775,8 +4781,8 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
47754781
}
47764782
}
47774783

4778-
hci_connect_cfm(conn, ev->status);
4779-
if (ev->status)
4784+
hci_connect_cfm(conn, status);
4785+
if (status)
47804786
hci_conn_del(conn);
47814787

47824788
unlock:
@@ -5527,11 +5533,6 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
55275533
struct smp_irk *irk;
55285534
u8 addr_type;
55295535

5530-
if (handle > HCI_CONN_HANDLE_MAX) {
5531-
bt_dev_err(hdev, "Ignoring HCI_LE_Connection_Complete for invalid handle");
5532-
return;
5533-
}
5534-
55355536
hci_dev_lock(hdev);
55365537

55375538
/* All controllers implicitly stop advertising in the event of a
@@ -5603,6 +5604,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
56035604

56045605
conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
56055606

5607+
if (handle > HCI_CONN_HANDLE_MAX) {
5608+
bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", handle,
5609+
HCI_CONN_HANDLE_MAX);
5610+
status = HCI_ERROR_INVALID_PARAMETERS;
5611+
}
5612+
56065613
if (status) {
56075614
hci_le_conn_failed(conn, status);
56085615
goto unlock;

0 commit comments

Comments
 (0)