Skip to content

Commit 8d73dab

Browse files
Vudentzxdevs23
authored andcommitted
Bluetooth: hci_event: Fix not using key encryption size when its known
This fixes the regression introduced by 50c1241e6a8a ("Bluetooth: l2cap: Check encryption key size on incoming connection") introduced a check for l2cap_check_enc_key_size which checks for hcon->enc_key_size which may not be initialized if HCI_OP_READ_ENC_KEY_SIZE is still pending. If the key encryption size is known, due previously reading it using HCI_OP_READ_ENC_KEY_SIZE, then store it as part of link_key/smp_ltk structures so the next time the encryption is changed their values are used as conn->enc_key_size thus avoiding the racing against HCI_OP_READ_ENC_KEY_SIZE. Now that the enc_size is stored as part of key the information the code then attempts to check that there is no downgrade of security if HCI_OP_READ_ENC_KEY_SIZE returns a value smaller than what has been previously stored. Link: https://bugzilla.kernel.org/show_bug.cgi?id=220061 Link: https://bugzilla.kernel.org/show_bug.cgi?id=220063 Fixes: 522e9ed ("Bluetooth: l2cap: Check encryption key size on incoming connection") Signed-off-by: Luiz Augusto von Dentz <[email protected]> Cherry-picked-for: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/137 Signed-off-by: Simão Gomes Viana <[email protected]>
1 parent f7ac25c commit 8d73dab

3 files changed

Lines changed: 67 additions & 31 deletions

File tree

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,7 @@ struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
17781778
void hci_uuids_clear(struct hci_dev *hdev);
17791779

17801780
void hci_link_keys_clear(struct hci_dev *hdev);
1781+
u8 *hci_conn_key_enc_size(struct hci_conn *conn);
17811782
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
17821783
struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
17831784
bdaddr_t *bdaddr, u8 *val, u8 type,

net/bluetooth/hci_conn.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,3 +2897,27 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
28972897
*/
28982898
return hci_cmd_sync_run_once(hdev, abort_conn_sync, conn, NULL);
28992899
}
2900+
2901+
u8 *hci_conn_key_enc_size(struct hci_conn *conn)
2902+
{
2903+
if (conn->type == ACL_LINK) {
2904+
struct link_key *key;
2905+
2906+
key = hci_find_link_key(conn->hdev, &conn->dst);
2907+
if (!key)
2908+
return NULL;
2909+
2910+
return &key->pin_len;
2911+
} else if (conn->type == LE_LINK) {
2912+
struct smp_ltk *ltk;
2913+
2914+
ltk = hci_find_ltk(conn->hdev, &conn->dst, conn->dst_type,
2915+
conn->role);
2916+
if (!ltk)
2917+
return NULL;
2918+
2919+
return &ltk->enc_size;
2920+
}
2921+
2922+
return NULL;
2923+
}

net/bluetooth/hci_event.c

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -739,10 +739,17 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
739739
handle);
740740
conn->enc_key_size = 0;
741741
} else {
742+
u8 *key_enc_size = hci_conn_key_enc_size(conn);
743+
742744
conn->enc_key_size = rp->key_size;
743745
status = 0;
744746

745-
if (conn->enc_key_size < hdev->min_enc_key_size) {
747+
/* Attempt to check if the key size is too small or if it has
748+
* been downgraded from the last time it was stored as part of
749+
* the link_key.
750+
*/
751+
if (conn->enc_key_size < hdev->min_enc_key_size ||
752+
(key_enc_size && conn->enc_key_size < *key_enc_size)) {
746753
/* As slave role, the conn->state has been set to
747754
* BT_CONNECTED and l2cap conn req might not be received
748755
* yet, at this moment the l2cap layer almost does
@@ -755,6 +762,10 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
755762
clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
756763
clear_bit(HCI_CONN_AES_CCM, &conn->flags);
757764
}
765+
766+
/* Update the key encryption size with the connection one */
767+
if (key_enc_size && *key_enc_size != conn->enc_key_size)
768+
*key_enc_size = conn->enc_key_size;
758769
}
759770

760771
hci_encrypt_cfm(conn, status);
@@ -3062,6 +3073,34 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
30623073
hci_dev_unlock(hdev);
30633074
}
30643075

3076+
static int hci_read_enc_key_size(struct hci_dev *hdev, struct hci_conn *conn)
3077+
{
3078+
struct hci_cp_read_enc_key_size cp;
3079+
u8 *key_enc_size = hci_conn_key_enc_size(conn);
3080+
3081+
if (!read_key_size_capable(hdev)) {
3082+
conn->enc_key_size = HCI_LINK_KEY_SIZE;
3083+
return -EOPNOTSUPP;
3084+
}
3085+
3086+
bt_dev_dbg(hdev, "hcon %p", conn);
3087+
3088+
memset(&cp, 0, sizeof(cp));
3089+
cp.handle = cpu_to_le16(conn->handle);
3090+
3091+
/* If the key enc_size is already known, use it as conn->enc_key_size,
3092+
* otherwise use hdev->min_enc_key_size so the likes of
3093+
* l2cap_check_enc_key_size don't fail while waiting for
3094+
* HCI_OP_READ_ENC_KEY_SIZE response.
3095+
*/
3096+
if (key_enc_size && *key_enc_size)
3097+
conn->enc_key_size = *key_enc_size;
3098+
else
3099+
conn->enc_key_size = hdev->min_enc_key_size;
3100+
3101+
return hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp);
3102+
}
3103+
30653104
static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30663105
struct sk_buff *skb)
30673106
{
@@ -3154,23 +3193,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31543193
if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
31553194
ev->link_type == ACL_LINK) {
31563195
struct link_key *key;
3157-
struct hci_cp_read_enc_key_size cp;
31583196

31593197
key = hci_find_link_key(hdev, &ev->bdaddr);
31603198
if (key) {
31613199
set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3162-
3163-
if (!read_key_size_capable(hdev)) {
3164-
conn->enc_key_size = HCI_LINK_KEY_SIZE;
3165-
} else {
3166-
cp.handle = cpu_to_le16(conn->handle);
3167-
if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
3168-
sizeof(cp), &cp)) {
3169-
bt_dev_err(hdev, "sending read key size failed");
3170-
conn->enc_key_size = HCI_LINK_KEY_SIZE;
3171-
}
3172-
}
3173-
3200+
hci_read_enc_key_size(hdev, conn);
31743201
hci_encrypt_cfm(conn, ev->status);
31753202
}
31763203
}
@@ -3609,24 +3636,8 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
36093636

36103637
/* Try reading the encryption key size for encrypted ACL links */
36113638
if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
3612-
struct hci_cp_read_enc_key_size cp;
3613-
3614-
/* Only send HCI_Read_Encryption_Key_Size if the
3615-
* controller really supports it. If it doesn't, assume
3616-
* the default size (16).
3617-
*/
3618-
if (!read_key_size_capable(hdev)) {
3619-
conn->enc_key_size = HCI_LINK_KEY_SIZE;
3620-
goto notify;
3621-
}
3622-
3623-
cp.handle = cpu_to_le16(conn->handle);
3624-
if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
3625-
sizeof(cp), &cp)) {
3626-
bt_dev_err(hdev, "sending read key size failed");
3627-
conn->enc_key_size = HCI_LINK_KEY_SIZE;
3639+
if (hci_read_enc_key_size(hdev, conn))
36283640
goto notify;
3629-
}
36303641

36313642
goto unlock;
36323643
}

0 commit comments

Comments
 (0)