diff mbox series

[v1,2/2] Bluetooth: MGMT: Attempt to fix up keys being loaded with invalid type

Message ID 20240827190655.675179-2-luiz.dentz@gmail.com
State New
Headers show
Series [v1,1/2] Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE" | expand

Commit Message

Luiz Augusto von Dentz Aug. 27, 2024, 7:06 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Due to 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 there could be keys stored
with the wrong address type so this attempt to detect it and fix them up,
in addition to that the commands are changed so that they are less
strict by just skipping keys considered invalid rather than failing to
load all keys.

Cc: stable@vger.kernel.org
Link: https://github.com/bluez/bluez/issues/875
Fixes: 59b047bc9808 ("Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/mgmt.c | 44 ++++++++++++++++++++++++++------------------
 1 file changed, 26 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 240dd8cf7c7d..9b41b5f9c571 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2830,15 +2830,6 @@  static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 	bt_dev_dbg(hdev, "debug_keys %u key_count %u", cp->debug_keys,
 		   key_count);
 
-	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)
-			return mgmt_cmd_status(sk, hdev->id,
-					       MGMT_OP_LOAD_LINK_KEYS,
-					       MGMT_STATUS_INVALID_PARAMS);
-	}
-
 	hci_dev_lock(hdev);
 
 	hci_link_keys_clear(hdev);
@@ -2863,6 +2854,19 @@  static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
 			continue;
 		}
 
+		/* Due to 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 there could
+		 * be keys stored with the wrong address type so this check it
+		 * and fix them up.
+		 */
+		if (key->addr.type != BDADDR_BREDR)
+			key->addr.type = BDADDR_BREDR;
+
+		if (key->type > 0x08) {
+			bt_dev_warn(hdev, "Invalid link key type %u for %pMR",
+				    key->type, &key->addr.bdaddr);
+			continue;
+		}
+
 		/* Always ignore debug keys and require a new pairing if
 		 * the user wants to use them.
 		 */
@@ -7117,6 +7121,13 @@  static bool ltk_is_valid(struct mgmt_ltk_info *key)
 		return false;
 
 	switch (key->addr.type) {
+	case BDADDR_BREDR:
+		/* Due to 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 there could
+		 * be keys stored with the wrong address type so this check it
+		 * and fix them up.
+		 */
+		key->addr.type = BDADDR_LE_PUBLIC;
+		return true;
 	case BDADDR_LE_PUBLIC:
 		return true;
 
@@ -7163,15 +7174,6 @@  static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 
 	bt_dev_dbg(hdev, "key_count %u", key_count);
 
-	for (i = 0; i < key_count; i++) {
-		struct mgmt_ltk_info *key = &cp->keys[i];
-
-		if (!ltk_is_valid(key))
-			return mgmt_cmd_status(sk, hdev->id,
-					       MGMT_OP_LOAD_LONG_TERM_KEYS,
-					       MGMT_STATUS_INVALID_PARAMS);
-	}
-
 	hci_dev_lock(hdev);
 
 	hci_smp_ltks_clear(hdev);
@@ -7188,6 +7190,12 @@  static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 			continue;
 		}
 
+		if (!ltk_is_valid(key)) {
+			bt_dev_warn(hdev, "Invalid LTK for %pMR",
+				    &key->addr.bdaddr);
+			continue;
+		}
+
 		switch (key->type) {
 		case MGMT_LTK_UNAUTHENTICATED:
 			authenticated = 0x00;