mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
bluetooth pull request for net:
- MGMT: Fix MGMT_OP_ADD_DEVICE invalid device flags - hci_event: Fix not using key encryption size when its known -----BEGIN PGP SIGNATURE----- iQJNBAABCgA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmgcyKYZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKWSqEACGdIL6oDrfUmE2mFUxlT2C eUSe1RDvXi63pFCxv4a1/JrnAICfIPbuKhvkOhf9g3JoQXjqdtX5REjEPcCndyBg sSyGGfxcaoYLsSWQY1nSb2p/bttk1R3LfPT78QhKPDsh63FkvRw77P++8anzG3T1 wqgjKU9XZb7zYmMElYCqYbnd0K2PymJtD+Oml1srBRdOpz1ex3s6Qj4Cy6cg07Vb SlxqWMnWZG0wfnusAFZ48zwYu/7/LQQnSJ6rbHSfrKLQnizNVvFTtsW+xrIfQ2m6 G7/WOX2LVwtP3XMe8VIDV0kdDtkDFtHq0KuNToAtt4DS582RHw0AVe+Xc2x5FFKA rmcukZLvg6tv/DM/PM5zJdvZW4M+r1IOnBSZvFMAdYb4Af04DHjI1k1ow9On6O3f oJCeRZ4LoOREljR+xdO/Ewn207za0wGR7IlDXFVpeGEOnLcSAxvqUl6biL3cEQpA bb97I7fjqwSPqpAGsMV0uhULTJxT7QPhF05rL3bpSzAzZoDpRFhc070TLBBuQvW1 zQmf+SCeg72vDtv1vsekyoXWfM+SpwlsNYuStPBztrKZgBGeRKjtZc2/L6dLPKbo bATO6Dhidm+outsF59YaqORFteON4yLAXSryLw6uVNIT3ApyUspNICyn4zi0tbYY 8N4rjTclIk5zV1z8zCJ7Lg== =uyVh -----END PGP SIGNATURE----- Merge tag 'for-net-2025-05-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - MGMT: Fix MGMT_OP_ADD_DEVICE invalid device flags - hci_event: Fix not using key encryption size when its known * tag 'for-net-2025-05-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_event: Fix not using key encryption size when its known Bluetooth: MGMT: Fix MGMT_OP_ADD_DEVICE invalid device flags ==================== Link: https://patch.msgid.link/20250508150927.385675-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
ea9a83d7f3
|
|
@ -1798,6 +1798,7 @@ struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
|
|||
void hci_uuids_clear(struct hci_dev *hdev);
|
||||
|
||||
void hci_link_keys_clear(struct hci_dev *hdev);
|
||||
u8 *hci_conn_key_enc_size(struct hci_conn *conn);
|
||||
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
|
||||
struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
bdaddr_t *bdaddr, u8 *val, u8 type,
|
||||
|
|
|
|||
|
|
@ -3023,3 +3023,27 @@ void hci_conn_tx_dequeue(struct hci_conn *conn)
|
|||
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
u8 *hci_conn_key_enc_size(struct hci_conn *conn)
|
||||
{
|
||||
if (conn->type == ACL_LINK) {
|
||||
struct link_key *key;
|
||||
|
||||
key = hci_find_link_key(conn->hdev, &conn->dst);
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
return &key->pin_len;
|
||||
} else if (conn->type == LE_LINK) {
|
||||
struct smp_ltk *ltk;
|
||||
|
||||
ltk = hci_find_ltk(conn->hdev, &conn->dst, conn->dst_type,
|
||||
conn->role);
|
||||
if (!ltk)
|
||||
return NULL;
|
||||
|
||||
return <k->enc_size;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -739,10 +739,17 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
|
|||
handle);
|
||||
conn->enc_key_size = 0;
|
||||
} else {
|
||||
u8 *key_enc_size = hci_conn_key_enc_size(conn);
|
||||
|
||||
conn->enc_key_size = rp->key_size;
|
||||
status = 0;
|
||||
|
||||
if (conn->enc_key_size < hdev->min_enc_key_size) {
|
||||
/* Attempt to check if the key size is too small or if it has
|
||||
* been downgraded from the last time it was stored as part of
|
||||
* the link_key.
|
||||
*/
|
||||
if (conn->enc_key_size < hdev->min_enc_key_size ||
|
||||
(key_enc_size && conn->enc_key_size < *key_enc_size)) {
|
||||
/* As slave role, the conn->state has been set to
|
||||
* BT_CONNECTED and l2cap conn req might not be received
|
||||
* 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,
|
|||
clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
|
||||
clear_bit(HCI_CONN_AES_CCM, &conn->flags);
|
||||
}
|
||||
|
||||
/* Update the key encryption size with the connection one */
|
||||
if (key_enc_size && *key_enc_size != conn->enc_key_size)
|
||||
*key_enc_size = conn->enc_key_size;
|
||||
}
|
||||
|
||||
hci_encrypt_cfm(conn, status);
|
||||
|
|
@ -3065,6 +3076,34 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
|
|||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static int hci_read_enc_key_size(struct hci_dev *hdev, struct hci_conn *conn)
|
||||
{
|
||||
struct hci_cp_read_enc_key_size cp;
|
||||
u8 *key_enc_size = hci_conn_key_enc_size(conn);
|
||||
|
||||
if (!read_key_size_capable(hdev)) {
|
||||
conn->enc_key_size = HCI_LINK_KEY_SIZE;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
bt_dev_dbg(hdev, "hcon %p", conn);
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
cp.handle = cpu_to_le16(conn->handle);
|
||||
|
||||
/* If the key enc_size is already known, use it as conn->enc_key_size,
|
||||
* otherwise use hdev->min_enc_key_size so the likes of
|
||||
* l2cap_check_enc_key_size don't fail while waiting for
|
||||
* HCI_OP_READ_ENC_KEY_SIZE response.
|
||||
*/
|
||||
if (key_enc_size && *key_enc_size)
|
||||
conn->enc_key_size = *key_enc_size;
|
||||
else
|
||||
conn->enc_key_size = hdev->min_enc_key_size;
|
||||
|
||||
return hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
|
|
@ -3157,23 +3196,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
|
|||
if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
|
||||
ev->link_type == ACL_LINK) {
|
||||
struct link_key *key;
|
||||
struct hci_cp_read_enc_key_size cp;
|
||||
|
||||
key = hci_find_link_key(hdev, &ev->bdaddr);
|
||||
if (key) {
|
||||
set_bit(HCI_CONN_ENCRYPT, &conn->flags);
|
||||
|
||||
if (!read_key_size_capable(hdev)) {
|
||||
conn->enc_key_size = HCI_LINK_KEY_SIZE;
|
||||
} else {
|
||||
cp.handle = cpu_to_le16(conn->handle);
|
||||
if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
|
||||
sizeof(cp), &cp)) {
|
||||
bt_dev_err(hdev, "sending read key size failed");
|
||||
conn->enc_key_size = HCI_LINK_KEY_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
hci_read_enc_key_size(hdev, conn);
|
||||
hci_encrypt_cfm(conn, ev->status);
|
||||
}
|
||||
}
|
||||
|
|
@ -3612,24 +3639,8 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
|
|||
|
||||
/* Try reading the encryption key size for encrypted ACL links */
|
||||
if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
|
||||
struct hci_cp_read_enc_key_size cp;
|
||||
|
||||
/* Only send HCI_Read_Encryption_Key_Size if the
|
||||
* controller really supports it. If it doesn't, assume
|
||||
* the default size (16).
|
||||
*/
|
||||
if (!read_key_size_capable(hdev)) {
|
||||
conn->enc_key_size = HCI_LINK_KEY_SIZE;
|
||||
if (hci_read_enc_key_size(hdev, conn))
|
||||
goto notify;
|
||||
}
|
||||
|
||||
cp.handle = cpu_to_le16(conn->handle);
|
||||
if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
|
||||
sizeof(cp), &cp)) {
|
||||
bt_dev_err(hdev, "sending read key size failed");
|
||||
conn->enc_key_size = HCI_LINK_KEY_SIZE;
|
||||
goto notify;
|
||||
}
|
||||
|
||||
goto unlock;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7506,11 +7506,16 @@ static void add_device_complete(struct hci_dev *hdev, void *data, int err)
|
|||
struct mgmt_cp_add_device *cp = cmd->param;
|
||||
|
||||
if (!err) {
|
||||
struct hci_conn_params *params;
|
||||
|
||||
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
|
||||
le_addr_type(cp->addr.type));
|
||||
|
||||
device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type,
|
||||
cp->action);
|
||||
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
|
||||
cp->addr.type, hdev->conn_flags,
|
||||
PTR_UINT(cmd->user_data));
|
||||
params ? params->flags : 0);
|
||||
}
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
||||
|
|
@ -7613,8 +7618,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
cmd->user_data = UINT_PTR(current_flags);
|
||||
|
||||
err = hci_cmd_sync_queue(hdev, add_device_sync, cmd,
|
||||
add_device_complete);
|
||||
if (err < 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user