Patch "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bluetooth-mgmt-smp-fix-address-type-when-using-smp-o.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 7636c9fd1b65c72bf332e2dd4bf090a937000c81
Author: Xiao Yao <xiaoyao@xxxxxxxxxxxxxx>
Date:   Tue Dec 12 00:27:18 2023 +0800

    Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE
    
    [ Upstream commit 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 ]
    
    If two Bluetooth devices both support BR/EDR and BLE, and also
    support Secure Connections, then they only need to pair once.
    The LTK generated during the LE pairing process may be converted
    into a BR/EDR link key for BR/EDR transport, and conversely, a
    link key generated during the BR/EDR SSP pairing process can be
    converted into an LTK for LE transport. Hence, the link type of
    the link key and LTK is not fixed, they can be either an LE LINK
    or an ACL LINK.
    
    Currently, in the mgmt_new_irk/ltk/crsk/link_key functions, the
    link type is fixed, which could lead to incorrect address types
    being reported to the application layer. Therefore, it is necessary
    to add link_type/addr_type to the smp_irk/ltk/crsk and link_key,
    to ensure the generation of the correct address type.
    
    SMP over BREDR:
    Before Fix:
    > ACL Data RX: Handle 11 flags 0x02 dlen 12
            BR/EDR SMP: Identity Address Information (0x09) len 7
            Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
    @ MGMT Event: New Identity Resolving Key (0x0018) plen 30
            Random address: 00:00:00:00:00:00 (Non-Resolvable)
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
    @ MGMT Event: New Long Term Key (0x000a) plen 37
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
            Key type: Authenticated key from P-256 (0x03)
    
    After Fix:
    > ACL Data RX: Handle 11 flags 0x02 dlen 12
          BR/EDR SMP: Identity Address Information (0x09) len 7
            Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
    @ MGMT Event: New Identity Resolving Key (0x0018) plen 30
            Random address: 00:00:00:00:00:00 (Non-Resolvable)
            BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
    @ MGMT Event: New Long Term Key (0x000a) plen 37
            BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
            Key type: Authenticated key from P-256 (0x03)
    
    SMP over LE:
    Before Fix:
    @ MGMT Event: New Identity Resolving Key (0x0018) plen 30
            Random address: 5F:5C:07:37:47:D5 (Resolvable)
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
    @ MGMT Event: New Long Term Key (0x000a) plen 37
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
            Key type: Authenticated key from P-256 (0x03)
    @ MGMT Event: New Link Key (0x0009) plen 26
            BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
            Key type: Authenticated Combination key from P-256 (0x08)
    
    After Fix:
    @ MGMT Event: New Identity Resolving Key (0x0018) plen 30
            Random address: 5E:03:1C:00:38:21 (Resolvable)
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
    @ MGMT Event: New Long Term Key (0x000a) plen 37
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
            Key type: Authenticated key from P-256 (0x03)
    @ MGMT Event: New Link Key (0x0009) plen 26
            Store hint: Yes (0x01)
            LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76)
            Key type: Authenticated Combination key from P-256 (0x08)
    
    Cc: stable@xxxxxxxxxxxxxxx
    Signed-off-by: Xiao Yao <xiaoyao@xxxxxxxxxxxxxx>
    Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e33433ec4a98f..a168a64696b6b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -174,6 +174,7 @@ struct blocked_key {
 struct smp_csrk {
 	bdaddr_t bdaddr;
 	u8 bdaddr_type;
+	u8 link_type;
 	u8 type;
 	u8 val[16];
 };
@@ -183,6 +184,7 @@ struct smp_ltk {
 	struct rcu_head rcu;
 	bdaddr_t bdaddr;
 	u8 bdaddr_type;
+	u8 link_type;
 	u8 authenticated;
 	u8 type;
 	u8 enc_size;
@@ -197,6 +199,7 @@ struct smp_irk {
 	bdaddr_t rpa;
 	bdaddr_t bdaddr;
 	u8 addr_type;
+	u8 link_type;
 	u8 val[16];
 };
 
@@ -204,6 +207,8 @@ struct link_key {
 	struct list_head list;
 	struct rcu_head rcu;
 	bdaddr_t bdaddr;
+	u8 bdaddr_type;
+	u8 link_type;
 	u8 type;
 	u8 val[HCI_LINK_KEY_SIZE];
 	u8 pin_len;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c62ea4c954645..bd8cfcfca7aef 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2373,7 +2373,8 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 	for (i = 0; i < key_count; i++) {
 		struct mgmt_link_key_info *key = &cp->keys[i];
 
-		if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
+		/* Considering SMP over BREDR/LE, there is no need to check addr_type */
+		if (key->type > 0x08)
 			return mgmt_cmd_status(sk, hdev->id,
 					       MGMT_OP_LOAD_LINK_KEYS,
 					       MGMT_STATUS_INVALID_PARAMS);
@@ -5914,6 +5915,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
 
 	for (i = 0; i < irk_count; i++) {
 		struct mgmt_irk_info *irk = &cp->irks[i];
+		u8 addr_type = le_addr_type(irk->addr.type);
 
 		if (hci_is_blocked_key(hdev,
 				       HCI_BLOCKED_KEY_TYPE_IRK,
@@ -5923,8 +5925,12 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
 			continue;
 		}
 
+		/* When using SMP over BR/EDR, the addr type should be set to BREDR */
+		if (irk->addr.type == BDADDR_BREDR)
+			addr_type = BDADDR_BREDR;
+
 		hci_add_irk(hdev, &irk->addr.bdaddr,
-			    le_addr_type(irk->addr.type), irk->val,
+			    addr_type, irk->val,
 			    BDADDR_ANY);
 	}
 
@@ -6005,6 +6011,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 	for (i = 0; i < key_count; i++) {
 		struct mgmt_ltk_info *key = &cp->keys[i];
 		u8 type, authenticated;
+		u8 addr_type = le_addr_type(key->addr.type);
 
 		if (hci_is_blocked_key(hdev,
 				       HCI_BLOCKED_KEY_TYPE_LTK,
@@ -6039,8 +6046,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 			continue;
 		}
 
+		/* When using SMP over BR/EDR, the addr type should be set to BREDR */
+		if (key->addr.type == BDADDR_BREDR)
+			addr_type = BDADDR_BREDR;
+
 		hci_add_ltk(hdev, &key->addr.bdaddr,
-			    le_addr_type(key->addr.type), type, authenticated,
+			    addr_type, type, authenticated,
 			    key->val, key->enc_size, key->ediv, key->rand);
 	}
 
@@ -8043,7 +8054,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
 
 	ev.store_hint = persistent;
 	bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
-	ev.key.addr.type = BDADDR_BREDR;
+	ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type);
 	ev.key.type = key->type;
 	memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE);
 	ev.key.pin_len = key->pin_len;
@@ -8094,7 +8105,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
 		ev.store_hint = persistent;
 
 	bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
-	ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
+	ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type);
 	ev.key.type = mgmt_ltk_type(key);
 	ev.key.enc_size = key->enc_size;
 	ev.key.ediv = key->ediv;
@@ -8123,7 +8134,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent)
 
 	bacpy(&ev.rpa, &irk->rpa);
 	bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
-	ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
+	ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type);
 	memcpy(ev.irk.val, irk->val, sizeof(irk->val));
 
 	mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
@@ -8152,7 +8163,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
 		ev.store_hint = persistent;
 
 	bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
-	ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
+	ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type);
 	ev.key.type = csrk->type;
 	memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index af6cc2e8c0284..0a95ccb160181 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1059,6 +1059,7 @@ static void smp_notify_keys(struct l2cap_conn *conn)
 	}
 
 	if (smp->remote_irk) {
+		smp->remote_irk->link_type = hcon->type;
 		mgmt_new_irk(hdev, smp->remote_irk, persistent);
 
 		/* Now that user space can be considered to know the
@@ -1073,24 +1074,28 @@ static void smp_notify_keys(struct l2cap_conn *conn)
 	}
 
 	if (smp->csrk) {
+		smp->csrk->link_type = hcon->type;
 		smp->csrk->bdaddr_type = hcon->dst_type;
 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
 		mgmt_new_csrk(hdev, smp->csrk, persistent);
 	}
 
 	if (smp->responder_csrk) {
+		smp->responder_csrk->link_type = hcon->type;
 		smp->responder_csrk->bdaddr_type = hcon->dst_type;
 		bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
 		mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
 	}
 
 	if (smp->ltk) {
+		smp->ltk->link_type = hcon->type;
 		smp->ltk->bdaddr_type = hcon->dst_type;
 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
 		mgmt_new_ltk(hdev, smp->ltk, persistent);
 	}
 
 	if (smp->responder_ltk) {
+		smp->responder_ltk->link_type = hcon->type;
 		smp->responder_ltk->bdaddr_type = hcon->dst_type;
 		bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
 		mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
@@ -1110,6 +1115,8 @@ static void smp_notify_keys(struct l2cap_conn *conn)
 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
 				       smp->link_key, type, 0, &persistent);
 		if (key) {
+			key->link_type = hcon->type;
+			key->bdaddr_type = hcon->dst_type;
 			mgmt_new_link_key(hdev, key, persistent);
 
 			/* Don't keep debug keys around if the relevant




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux